diff --git a/game/client/src/main/java/net/betterthanadventure/utils/BiomeFinder.java b/game/client/src/main/java/net/betterthanadventure/utils/BiomeFinder.java
index e261188f4..ee424dc59 100644
--- a/game/client/src/main/java/net/betterthanadventure/utils/BiomeFinder.java
+++ b/game/client/src/main/java/net/betterthanadventure/utils/BiomeFinder.java
@@ -498,7 +498,7 @@ public class BiomeFinder implements MinecraftAccessor {
 		} else {
 			SaveFormatBase saveFormat = new SaveFormat19134(worldFolder.getParentFile());
 			LevelStorage saveHandler = saveFormat.getSaveHandler(worldFolder.getName(), false);
-			world = new World(saveHandler, saveHandler.getLevelData().getWorldName(), saveHandler.getLevelData().getRandomSeed(), null, null);
+			world = new World(saveHandler, saveHandler.getLevelData().getWorldName(), saveHandler.getLevelData().getRandomSeed(), null, null, null);
 			biomeProvider = worldType.createBiomeProvider(world);
 		}
 		allBiomes.clear();
diff --git a/game/client/src/main/java/net/minecraft/client/GLAllocation.java b/game/client/src/main/java/net/minecraft/client/GLAllocation.java
index 91378c500..fc478c556 100644
--- a/game/client/src/main/java/net/minecraft/client/GLAllocation.java
+++ b/game/client/src/main/java/net/minecraft/client/GLAllocation.java
@@ -1,12 +1,12 @@
 package net.minecraft.client;
 
-import java.nio.*;
-
 import it.unimi.dsi.fastutil.ints.IntArrayList;
 import it.unimi.dsi.fastutil.ints.IntList;
 import org.lwjgl.BufferUtils;
 import org.lwjgl.opengl.GL41;
 
+import java.nio.IntBuffer;
+
 public class GLAllocation {
 	
 	public static IntList textureNames = new IntArrayList();
@@ -29,8 +29,7 @@ public class GLAllocation {
 		}
 	}
 
-	public static synchronized void deleteTexturesAndDisplayLists() {
-
+	public static synchronized void deleteTextures() {
 		IntBuffer intbuffer = BufferUtils.createIntBuffer(textureNames.size());
 		for (Integer textureName : textureNames) {
 			intbuffer.put(textureName);
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 a12f7f9d2..a0b3b198c 100644
--- a/game/client/src/main/java/net/minecraft/client/Minecraft.java
+++ b/game/client/src/main/java/net/minecraft/client/Minecraft.java
@@ -1,127 +1,45 @@
 package net.minecraft.client;
 
-import java.awt.Cursor;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.io.File;
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.nio.file.Files;
-import java.util.*;
-
 import com.mojang.logging.LogUtils;
 import com.mojang.nbt.tags.CompoundTag;
 import it.unimi.dsi.fastutil.objects.Object2LongLinkedOpenHashMap;
 import it.unimi.dsi.fastutil.objects.Object2LongMap;
 import net.minecraft.client.console.LogMessageReceiver;
 import net.minecraft.client.console.shell.BindManager;
+import net.minecraft.client.discord.RichPresenceHandlerThread;
 import net.minecraft.client.entity.ClientSkinVariantList;
 import net.minecraft.client.entity.player.PlayerLocal;
+import net.minecraft.client.entity.player.PlayerLocalMultiplayer;
 import net.minecraft.client.enums.EnumGPUVendor;
-import net.minecraft.client.gui.*;
+import net.minecraft.client.gui.ExceptionPopupElement;
+import net.minecraft.client.gui.MainMenuBackground;
+import net.minecraft.client.gui.Screen;
+import net.minecraft.client.gui.ScreenConnecting;
+import net.minecraft.client.gui.ScreenConsole;
+import net.minecraft.client.gui.ScreenGameOver;
+import net.minecraft.client.gui.ScreenMainMenu;
+import net.minecraft.client.gui.ScreenPause;
+import net.minecraft.client.gui.ScreenPhotoMode;
+import net.minecraft.client.gui.ScreenSleepSP;
+import net.minecraft.client.gui.ScreenStats;
+import net.minecraft.client.gui.TooltipElement;
 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.container.ScreenInventory;
+import net.minecraft.client.gui.container.ScreenInventoryCreative;
 import net.minecraft.client.gui.error.ScreenBadJavaArch;
 import net.minecraft.client.gui.error.ScreenConflictWarning;
 import net.minecraft.client.gui.error.ScreenMissingMinecraft;
 import net.minecraft.client.gui.error.ScreenOutOfMemory;
+import net.minecraft.client.gui.hud.HudIngame;
+import net.minecraft.client.gui.modelviewer.ScreenModelViewer;
 import net.minecraft.client.gui.options.data.OptionsPages;
+import net.minecraft.client.gui.popup.PopupScreen;
 import net.minecraft.client.gui.server.ScreenSelectServer;
+import net.minecraft.client.gui.subtitles.SubtitleTracker;
 import net.minecraft.client.gui.toasts.GuiElementToastsHud;
 import net.minecraft.client.holiday.Holidays;
-import net.minecraft.client.player.controller.PlayerControllerSP;
-import net.minecraft.client.render.EntityRendererDispatcher;
-import net.minecraft.client.render.block.color.BlockColorDispatcher;
-import net.minecraft.client.render.renderer.CompareFunc;
-import net.minecraft.client.render.renderer.CullFace;
-import net.minecraft.client.render.renderer.GLRenderer;
-import net.minecraft.client.render.renderer.Shaders;
-import net.minecraft.client.render.renderer.State;
-import net.minecraft.client.world.chunk.provider.ChunkProviderDynamic;
-import net.minecraft.client.world.chunk.provider.ChunkProviderThreadedClient;
-import net.minecraft.client.world.save.SaveHandlerClientSP;
-import net.minecraft.client.net.handler.PacketHandlerClient;
-import net.minecraft.client.render.TileEntityRenderDispatcher;
-import net.minecraft.client.render.font.FontRenderer;
-import net.minecraft.client.render.font.FontRendererDefault;
-import net.minecraft.client.render.terrain.TerrainRendererMultiDraw;
-import net.minecraft.client.util.helper.UrlHelper;
-import net.minecraft.client.world.WorldClient;
-import net.minecraft.client.world.WorldClientMP;
-import net.minecraft.client.world.chunk.provider.ChunkProviderStatic;
-import net.minecraft.core.achievement.Achievements;
-import net.minecraft.core.block.BlockLogicLeavesBase;
-import net.minecraft.core.block.entity.TileEntityDispatcher;
-import net.minecraft.core.entity.EntityDispatcher;
-import net.minecraft.core.net.command.CommandManager;
-import net.minecraft.core.net.command.commands.CommandAchievement;
-import net.minecraft.core.net.command.commands.CommandBiome;
-import net.minecraft.core.net.command.commands.CommandChunk;
-import net.minecraft.core.net.command.commands.CommandClear;
-import net.minecraft.core.net.command.commands.CommandClone;
-import net.minecraft.core.net.command.commands.CommandDamage;
-import net.minecraft.core.net.command.commands.CommandFill;
-import net.minecraft.core.net.command.commands.CommandGameMode;
-import net.minecraft.core.net.command.commands.CommandGameRule;
-import net.minecraft.core.net.command.commands.CommandGive;
-import net.minecraft.core.net.command.commands.CommandHeal;
-import net.minecraft.core.net.command.commands.CommandHelp;
-import net.minecraft.core.net.command.commands.CommandKill;
-import net.minecraft.core.net.command.commands.CommandMessage;
-import net.minecraft.core.net.command.commands.CommandMobSpawning;
-import net.minecraft.core.net.command.commands.CommandPlace;
-import net.minecraft.core.net.command.commands.CommandPlaySound;
-import net.minecraft.core.net.command.commands.CommandSay;
-import net.minecraft.core.net.command.commands.CommandSeed;
-import net.minecraft.core.net.command.commands.CommandSetBlock;
-import net.minecraft.core.net.command.commands.CommandSetSpawn;
-import net.minecraft.core.net.command.commands.CommandSpawn;
-import net.minecraft.core.net.command.commands.CommandParticle;
-import net.minecraft.core.net.command.commands.CommandSummon;
-import net.minecraft.core.net.command.commands.CommandTeleport;
-import net.minecraft.core.net.command.commands.CommandTellRaw;
-import net.minecraft.core.net.command.commands.CommandTestFor;
-import net.minecraft.core.net.command.commands.CommandTime;
-import net.minecraft.core.net.command.commands.CommandWeather;
-import net.minecraft.core.net.command.util.CommandHelper;
-import net.minecraft.core.player.gamemode.Gamemodes;
-import net.minecraft.core.util.pool.ObjectPool;
-import net.minecraft.core.util.helper.Color;
-import net.minecraft.core.util.helper.DyeColor;
-import net.minecraft.core.util.helper.LoggedPrintStream;
-import net.minecraft.core.util.helper.UUIDHelper;
-import net.minecraft.core.world.pos.TilePos;
-import net.minecraft.core.world.pos.TilePosc;
-import net.minecraft.core.world.save.SaveFormatBase;
-import net.minecraft.core.world.settings.WorldConfiguration;
-import net.minecraft.core.world.type.WorldType;
-
-import javax.imageio.ImageIO;
-import javax.swing.JLabel;
-import javax.swing.JOptionPane;
-
-import net.minecraft.client.gui.subtitles.SubtitleTracker;
-import net.minecraft.client.sound.SoundRepository;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import org.joml.Matrix4f;
-import org.joml.primitives.AABBd;
-import org.joml.primitives.AABBdc;
-import org.lwjgl.LWJGLException;
-import org.lwjgl.glfw.GLFW;
-import org.lwjgl.input.Keyboard;
-import org.lwjgl.input.Mouse;
-
-import net.minecraft.client.discord.RichPresenceHandlerThread;
-import net.minecraft.client.entity.player.PlayerLocalMultiplayer;
-import net.minecraft.client.gui.hud.HudIngame;
-import net.minecraft.client.gui.container.ScreenInventory;
-import net.minecraft.client.gui.container.ScreenInventoryCreative;
-import net.minecraft.client.gui.modelviewer.ScreenModelViewer;
-import net.minecraft.client.gui.popup.PopupScreen;
 import net.minecraft.client.input.InputDevice;
 import net.minecraft.client.input.InputHandler;
 import net.minecraft.client.input.InputType;
@@ -129,48 +47,73 @@ import net.minecraft.client.input.MouseInput;
 import net.minecraft.client.input.PlayerInput;
 import net.minecraft.client.input.controller.ControllerInput;
 import net.minecraft.client.input.controller.Joystick;
+import net.minecraft.client.net.handler.PacketHandlerClient;
 import net.minecraft.client.net.thread.ThreadDownloadResources;
 import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.option.KeyBinding;
 import net.minecraft.client.option.enums.LightmapStyle;
 import net.minecraft.client.player.controller.PlayerController;
-import net.minecraft.client.render.ParticleEngine;
+import net.minecraft.client.player.controller.PlayerControllerSP;
+import net.minecraft.client.render.EntityRendererDispatcher;
 import net.minecraft.client.render.LoadingScreenRenderer;
 import net.minecraft.client.render.OpenGLHelper;
+import net.minecraft.client.render.ParticleEngine;
 import net.minecraft.client.render.PostProcessingManager;
-import net.minecraft.client.render.TextureManager;
 import net.minecraft.client.render.RenderGlobal;
 import net.minecraft.client.render.Renderer;
+import net.minecraft.client.render.TextureManager;
+import net.minecraft.client.render.TileEntityRenderDispatcher;
 import net.minecraft.client.render.WorldRenderer;
+import net.minecraft.client.render.block.color.BlockColorDispatcher;
 import net.minecraft.client.render.block.model.BlockModelDispatcher;
 import net.minecraft.client.render.camera.EntityCameraFirstPerson;
 import net.minecraft.client.render.camera.ICamera;
 import net.minecraft.client.render.colorizer.Colorizers;
+import net.minecraft.client.render.font.FontRenderer;
+import net.minecraft.client.render.font.FontRendererDefault;
 import net.minecraft.client.render.item.model.ItemModelDispatcher;
+import net.minecraft.client.render.renderer.CompareFunc;
+import net.minecraft.client.render.renderer.CullFace;
+import net.minecraft.client.render.renderer.GLRenderer;
+import net.minecraft.client.render.renderer.Shaders;
+import net.minecraft.client.render.renderer.State;
 import net.minecraft.client.render.shader.ShadersRenderer;
 import net.minecraft.client.render.terrain.ChunkRenderer;
 import net.minecraft.client.render.terrain.TerrainRenderer;
+import net.minecraft.client.render.terrain.TerrainRendererMultiDraw;
 import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.client.render.texturepack.TexturePackList;
 import net.minecraft.client.render.window.GameWindow;
 import net.minecraft.client.render.window.GameWindowGLFW;
 import net.minecraft.client.sound.SoundEngine;
-import net.minecraft.core.util.debug.Debug;
+import net.minecraft.client.sound.SoundRepository;
 import net.minecraft.client.util.debug.DebugRender;
+import net.minecraft.client.util.helper.ScreenShot;
 import net.minecraft.client.util.helper.ScreenshotHelper;
 import net.minecraft.client.util.helper.Textures;
+import net.minecraft.client.util.helper.UrlHelper;
+import net.minecraft.client.world.WorldClient;
+import net.minecraft.client.world.WorldClientMP;
+import net.minecraft.client.world.chunk.provider.ChunkProviderDynamic;
+import net.minecraft.client.world.chunk.provider.ChunkProviderStatic;
+import net.minecraft.client.world.chunk.provider.ChunkProviderThreadedClient;
+import net.minecraft.client.world.save.SaveHandlerClientSP;
 import net.minecraft.core.Global;
 import net.minecraft.core.MinecraftAccessor;
 import net.minecraft.core.MinecraftError;
 import net.minecraft.core.MinecraftException;
 import net.minecraft.core.Timer;
 import net.minecraft.core.UnexpectedThrowable;
+import net.minecraft.core.achievement.Achievements;
 import net.minecraft.core.achievement.stat.StatList;
 import net.minecraft.core.achievement.stat.StatsCounter;
+import net.minecraft.core.block.BlockLogicLeavesBase;
 import net.minecraft.core.block.Blocks;
+import net.minecraft.core.block.entity.TileEntityDispatcher;
 import net.minecraft.core.data.DataLoader;
 import net.minecraft.core.data.registry.Registries;
+import net.minecraft.core.entity.EntityDispatcher;
 import net.minecraft.core.entity.EntityItem;
 import net.minecraft.core.entity.SkinVariantList;
 import net.minecraft.core.entity.player.Player;
@@ -179,16 +122,53 @@ import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.net.PlayerProfile;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.TextFormatting;
+import net.minecraft.core.net.command.commands.CommandAchievement;
+import net.minecraft.core.net.command.commands.CommandBiome;
+import net.minecraft.core.net.command.commands.CommandChunk;
+import net.minecraft.core.net.command.commands.CommandClear;
+import net.minecraft.core.net.command.commands.CommandClone;
+import net.minecraft.core.net.command.commands.CommandDamage;
+import net.minecraft.core.net.command.commands.CommandFill;
+import net.minecraft.core.net.command.commands.CommandGameMode;
+import net.minecraft.core.net.command.commands.CommandGameRule;
+import net.minecraft.core.net.command.commands.CommandGive;
+import net.minecraft.core.net.command.commands.CommandHeal;
+import net.minecraft.core.net.command.commands.CommandHelp;
+import net.minecraft.core.net.command.commands.CommandKill;
+import net.minecraft.core.net.command.commands.CommandMessage;
+import net.minecraft.core.net.command.commands.CommandMobSpawning;
+import net.minecraft.core.net.command.commands.CommandParticle;
+import net.minecraft.core.net.command.commands.CommandPlace;
+import net.minecraft.core.net.command.commands.CommandPlaySound;
+import net.minecraft.core.net.command.commands.CommandSay;
+import net.minecraft.core.net.command.commands.CommandSeed;
+import net.minecraft.core.net.command.commands.CommandSetBlock;
+import net.minecraft.core.net.command.commands.CommandSetSpawn;
+import net.minecraft.core.net.command.commands.CommandSpawn;
+import net.minecraft.core.net.command.commands.CommandSummon;
+import net.minecraft.core.net.command.commands.CommandTeleport;
+import net.minecraft.core.net.command.commands.CommandTellRaw;
+import net.minecraft.core.net.command.commands.CommandTestFor;
+import net.minecraft.core.net.command.commands.CommandTime;
+import net.minecraft.core.net.command.commands.CommandWeather;
+import net.minecraft.core.net.command.util.CommandHelper;
 import net.minecraft.core.player.Session;
 import net.minecraft.core.player.gamemode.Gamemode;
+import net.minecraft.core.player.gamemode.Gamemodes;
+import net.minecraft.core.util.debug.Debug;
 import net.minecraft.core.util.helper.Axis;
+import net.minecraft.core.util.helper.Color;
 import net.minecraft.core.util.helper.Direction;
+import net.minecraft.core.util.helper.DyeColor;
+import net.minecraft.core.util.helper.LoggedPrintStream;
 import net.minecraft.core.util.helper.MathHelper;
-import net.minecraft.client.util.helper.ScreenShot;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.util.helper.Time;
+import net.minecraft.core.util.helper.UUIDHelper;
 import net.minecraft.core.util.phys.HitResult;
+import net.minecraft.core.util.pool.ObjectPool;
 import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.PortalHandler;
 import net.minecraft.core.world.World;
@@ -197,19 +177,49 @@ import net.minecraft.core.world.chunk.Chunk;
 import net.minecraft.core.world.chunk.ChunkCoordinates;
 import net.minecraft.core.world.chunk.IChunkLoader;
 import net.minecraft.core.world.chunk.provider.IChunkProvider;
+import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.save.DimensionData;
 import net.minecraft.core.world.save.ISaveConverter;
 import net.minecraft.core.world.save.ISaveFormat;
 import net.minecraft.core.world.save.LevelData;
 import net.minecraft.core.world.save.LevelStorage;
 import net.minecraft.core.world.save.SaveConverters;
+import net.minecraft.core.world.save.SaveFormatBase;
 import net.minecraft.core.world.save.SaveFormats;
 import net.minecraft.core.world.save.mcregion.SaveFormat19134;
+import net.minecraft.core.world.settings.WorldConfiguration;
+import net.minecraft.core.world.type.WorldType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.joml.Matrix4f;
+import org.joml.primitives.AABBd;
+import org.joml.primitives.AABBdc;
+import org.lwjgl.LWJGLException;
+import org.lwjgl.glfw.GLFW;
+import org.lwjgl.input.Keyboard;
+import org.lwjgl.input.Mouse;
 import org.lwjgl.opengl.GL41;
 import org.lwjgl.system.Configuration;
 import org.slf4j.Logger;
 import org.useless.dragonfly.data.entity.mojang.EntityGeometryMojangData;
 
+import javax.imageio.ImageIO;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.io.File;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+import java.util.Random;
+import java.util.UUID;
 
 import static net.minecraft.core.Global.CURRENT_SAVE_VERSION;
 
@@ -250,7 +260,6 @@ public class Minecraft
     public HudIngame hudIngame;
     public boolean skipRenderWorld;
     public @Nullable HitResult objectMouseOver;
-    public final @NotNull GameSettings gameSettings;
     public @NotNull SoundEngine sndManager;
     public final @NotNull SubtitleTracker subtitleTracker = new SubtitleTracker();
     public final @NotNull TexturePackList texturePackList;
@@ -325,9 +334,8 @@ public class Minecraft
         INSTANCE = this;
 
         this.mcDataDir = mcDataDir;
-        this.gameSettings = new GameSettings(this, mcDataDir);
         this.texturePackList = new TexturePackList(this, this.mcDataDir);
-        this.textureManager = new TextureManager(this, this.texturePackList, this.gameSettings);
+        this.textureManager = new TextureManager(this, this.texturePackList);
         this.font = new FontRendererDefault();
 
         if (test) return;
@@ -387,21 +395,20 @@ public class Minecraft
         if (!this.gameStarted) {
             this.running = false;
 
-            LOGGER.error("An exception has occurred while trying to start the game!", throwable.exception);
+            LOGGER.error("An exception has occurred while trying to start the game!\n{}", throwable.description, throwable.exception);
 
-            this.gameWindow.displayCrashReport(throwable, 1);
+//            this.gameWindow.displayCrashReport(throwable, 1);
             this.hasCrashed = true;
             shutdownMinecraftApplet();
             return;
         }
 
-        boolean disableCrashHandler = this.gameSettings.disableCrashHandler.value;
-        if (disableCrashHandler) {
+        if (GameSettings.DISABLE_CRASH_HANDLER.value) {
             this.running = false;
 
-            LOGGER.error("An exception has occurred while trying to start the game!", throwable.exception);
+            LOGGER.error("An exception has occurred while trying to start the game!\n{}", throwable.description, throwable.exception);
 
-            this.gameWindow.displayCrashReport(throwable, 1);
+//            this.gameWindow.displayCrashReport(throwable, 1);
             this.hasCrashed = true;
             shutdownMinecraftApplet();
             return;
@@ -410,9 +417,9 @@ public class Minecraft
         if (this.hasCrashed) {
             this.running = false;
 
-            LOGGER.error("An exception has occurred while trying to start the game!", throwable.exception);
+            LOGGER.error("An exception has occurred while trying to start the game!\n{}", throwable.description, throwable.exception);
 
-            this.gameWindow.displayCrashReport(throwable, 2);
+//            this.gameWindow.displayCrashReport(throwable, 2);
             shutdownMinecraftApplet();
             return;
         }
@@ -481,7 +488,6 @@ public class Minecraft
     public void startGame() throws LWJGLException {
         // Initialize LogMessageReceiver to capture output
         LogMessageReceiver.init();
-
         Holidays.initialize();
 
         // Manually initialize blocks and items
@@ -493,15 +499,13 @@ public class Minecraft
         CommandHelper.init();
         initCommands();
 
-        this.gameSettings.init();
+        GameSettings.init(this.mcDataDir);
 
-        UUIDHelper.urlUUID = this.gameSettings.uuidServer.value;
+        UUIDHelper.urlUUID = GameSettings.UUID_SERVER.value;
 
         LOGGER.info("Java Version: {}", System.getProperty("java.version"));
 
-        printWrongJavaVersionInfo();
-
-        this.gameWindow.init(this, this.overrideWidth != null ? this.overrideWidth : this.gameSettings.windowWidth.value, this.overrideHeight != null ? this.overrideHeight : this.gameSettings.windowHeight.value);
+        this.gameWindow.init(this, this.overrideWidth != null ? this.overrideWidth : GameSettings.WINDOW_WIDTH.value, this.overrideHeight != null ? this.overrideHeight : GameSettings.WINDOW_HEIGHT.value);
         this.font.init();
 
         final @Nullable String vendorString = GL41.glGetString(GL41.GL_VENDOR);
@@ -511,18 +515,18 @@ public class Minecraft
 
         LOGGER.info("Resolution: {} x {}", this.gameWindow.getWidthPixels(), this.gameWindow.getHeightPixels());
 
-        this.resolution.setScale(this.gameSettings.guiScale.value);
+        this.resolution.setScale(GameSettings.GUI_SCALE.value);
 
         SaveFormatBase handlerBase = new SaveFormat19134(new File(this.mcDataDir, "saves"));
         handlerBase.factory = SaveHandlerClientSP::new;
         this.saveFormat = handlerBase;
-        I18n.initialize(this.gameSettings.language.value);
+        I18n.initialize(GameSettings.LANGUAGE.value);
 
-        if (!this.gameSettings.startInFullscreen.value) {
-            this.gameSettings.fullscreen.value = false;
+        if (!GameSettings.START_IN_FULLSCREEN.value) {
+            GameSettings.FULLSCREEN.value = false;
         }
 
-        this.resolution.setScale(this.gameSettings.guiScale.value);
+        this.resolution.setScale(GameSettings.GUI_SCALE.value);
 
         this.terrainRenderer = new TerrainRendererMultiDraw(this);
 
@@ -536,7 +540,6 @@ public class Minecraft
         SoundRepository.initialize(this);
 
         GLRenderer.init();
-
         // Show load screen as early as possible
         // Do not put stuff that takes a while to load before this,
         // otherwise the loading time will happen while the window is black
@@ -554,16 +557,15 @@ public class Minecraft
         ItemModelDispatcher.getInstance();
 
         loadScreen();    // Update loading screen so it doesn't say no response
-
         LOGGER.info("Initializing input");
         try {
             InputHandler.init(this);
 
-            this.controllerInput = InputHandler.getController(this.gameSettings.selectedController.value);
+            this.controllerInput = InputHandler.getController(GameSettings.SELECTED_CONTROLLER.value);
         } catch (Exception e) {
             LOGGER.error("Input init error!", e);
         }
-        this.mouseInput.setRawInput(this.gameSettings.rawMouseInput.value);
+        this.mouseInput.setRawInput(GameSettings.RAW_MOUSE_INPUT.value);
         LOGGER.info("Input done!");
 
         LOGGER.info("Setting up OpenGL values...");
@@ -576,7 +578,7 @@ public class Minecraft
         GLRenderer.projectionM4f().identity();
         GLRenderer.viewM4f().identity();
         OpenGLHelper.checkError("startup");
-        this.sndManager.init(this.gameSettings);
+        this.sndManager.init();
 
         loadScreen();    // Update loading screen so it doesn't say no response
 
@@ -627,22 +629,22 @@ public class Minecraft
         StatList.init();
         this.statsCounter = new StatsCounter(this.session, this.mcDataDir);
         Achievements.OPEN_INVENTORY.setDescriptionFormatter(s -> {
-            if (!this.gameSettings.keyInventory.isBound()) {
+            if (!GameSettings.KEY_INVENTORY.isBound()) {
                 return "Set your inventory keybind in the controls menu!";
             }
-            return String.format(s, this.gameSettings.keyInventory.getKeyName());
+            return String.format(s, GameSettings.KEY_INVENTORY.getKeyName());
         });
         Achievements.OPEN_GUIDEBOOK.setDescriptionFormatter(s -> {
-            if (!this.gameSettings.keyGuidebook.isBound()) {
+            if (!GameSettings.KEY_GUIDEBOOK.isBound()) {
                 return "Set your guidebook keybind in the controls menu!";
             }
-            return String.format(s, this.gameSettings.keyGuidebook.getKeyName());
+            return String.format(s, GameSettings.KEY_GUIDEBOOK.getKeyName());
         });
 
         loadScreen();    // Update loading screen so it doesn't say no response
 
         // Enable Discord Rich Presence
-        if (this.gameSettings.discordRichPresence.value) {
+        if (GameSettings.DISCORD_RICH_PRESENCE.value) {
             // This thing takes forever to load, so it has been moved down here,
             // so that the loading time is spent on the loading screen and not a black screen
             this.rpcThread = new RichPresenceHandlerThread(this);
@@ -709,26 +711,6 @@ public class Minecraft
         CommandManager.registerCommand(new CommandParticle());
     }
 
-    private void printWrongJavaVersionInfo() {
-        String javaVersion = System.getProperty("java.version");
-        if (getOs() != EnumOS.linux || javaVersion == null) {
-            return;
-        }
-        try {
-            int major = Integer.parseInt(javaVersion.split("\\.")[0]);
-            if (major > 8) {
-                LOGGER.warn("Detected a probably incompatible Java version. If the game crashes with a message similar to \n"
-                    + "\"Inconsistency detected by ld.so: dl-lookup.c: 111: check_match: Assertion `version->filename == NULL || ! _dl_name_match_p (version->filename, map)' failed!\", \n"
-                    + "use Java 8!");
-            }
-        } catch (Exception e) {
-            LOGGER.error("Failed to retrieve Java version!", e);
-            LOGGER.warn("If the game crashes with a message similar to \n"
-                + "\"Inconsistency detected by ld.so: dl-lookup.c: 111: check_match: Assertion `version->filename == NULL || ! _dl_name_match_p (version->filename, map)' failed!\", \n"
-                + "use Java 8!");
-        }
-    }
-
     public @NotNull Matrix4f getGuiProjectionMatrix(@NotNull Matrix4f dest) {
         return dest.identity().ortho(0.0f, (float) this.resolution.getExactScaledWidthScreenCoords(), (float) this.resolution.getExactScaledHeightScreenCoords(), 0.0f, 1000f, 3000f);
     }
@@ -794,7 +776,7 @@ public class Minecraft
 
     @Override
     public IChunkProvider createChunkProvider(World world, IChunkLoader chunkLoader) {
-        return switch (this.gameSettings.enableThreadedChunkProvider.value) {
+        return switch (GameSettings.CHUNK_PROVIDER.value) {
             case DYNAMIC ->
                 new ChunkProviderDynamic(world, chunkLoader, world.getWorldType().createChunkGenerator(world));
 
@@ -891,32 +873,43 @@ public class Minecraft
     }
 
     public void shutdownMinecraftApplet() {
-        // This could be called very early if the game crashes, so everything could be null!
+        LOGGER.info("Shutting Down");
         try {
-            if (this.gameSettings != null) {
-                this.gameSettings.saveOptions();
-            }
-        } catch (Exception e) {
+            GameSettings.saveOptions();
+        } catch (Throwable e) {
             LOGGER.error("Exception occurred while saving settings! Some settings may be lost!", e);
         }
         if (this.statsCounter != null) {
-            this.statsCounter.fetchStats();
-            this.statsCounter.saveStats();
+            try {
+                this.statsCounter.fetchStats();
+                this.statsCounter.saveStats();
+            } catch (Throwable throwable) {
+                LOGGER.error("Failed to save stats!");
+            }
         }
-        LOGGER.info("Stopping!");
-        try {
-            changeWorld(null);
-        } catch (Throwable ignored) {
+        if (this.currentWorld != null) {
+            try {
+                changeWorld(null);
+            } catch (Throwable throwable) {
+                LOGGER.error("Failed to close world!", throwable);
+            }
         }
         try {
-            GLAllocation.deleteTexturesAndDisplayLists();
-        } catch (Throwable ignored) {
+            if (OpenGLHelper.contextCreated) {
+                GLAllocation.deleteTextures();
+            }
+        } catch (Throwable throwable) {
+            LOGGER.error("Failed to free texture handles!", throwable);
         }
-        if (this.sndManager != null) {
+        try {
             this.sndManager.destroy();
+        } catch (Throwable throwable) {
+            LOGGER.error("Failed to close sound manager!", throwable);
         }
-        if (this.gameWindow != null) {
+        try {
             this.gameWindow.free();
+        } catch (Throwable throwable) {
+            LOGGER.error("Failed to free window resources!", throwable);
         }
         System.gc();
         if (!this.hasCrashed) {
@@ -986,8 +979,8 @@ public class Minecraft
                     Debug.push("misc");        // 2
 
                     OpenGLHelper.checkError("pre render");
-                    EntityItem.enableItemClumping = this.gameSettings.enableItemClumping.value;
-                    BlockLogicLeavesBase.enableTreeShadowing = this.gameSettings.treeShadows.value;
+                    EntityItem.enableItemClumping = GameSettings.ENABLE_ITEM_CLUMPING.value;
+                    BlockLogicLeavesBase.enableTreeShadowing = GameSettings.TREE_SHADOWS.value;
                     this.sndManager.updateListener(this.thePlayer, this.timer.partialTicks);
 //                    glEnable(GL_TEXTURE_2D);
                     if (this.currentWorld != null) {
@@ -1004,7 +997,7 @@ public class Minecraft
                     Debug.change("misc"); // 2
 
                     if (this.thePlayer != null && this.thePlayer.isInWall()) {
-                        this.gameSettings.thirdPersonView.value = 0;
+                        GameSettings.THIRD_PERSON_VIEW.value = 0;
                     }
 
                     Debug.change("displayupdate"); // 2
@@ -1024,7 +1017,7 @@ public class Minecraft
                         this.worldRenderer.updateCameraAndRender(this.timer.partialTicks);
                     }
 
-                    if (this.gameSettings.pauseOnLostFocus.value) {
+                    if (GameSettings.PAUSE_ON_LOST_FOCUS.value) {
                         if (!this.gameWindow.isFocused()) {
                             if (System.currentTimeMillis() > this.lastFocusTime + 250) {
                                 displayInGameMenu();
@@ -1033,7 +1026,7 @@ public class Minecraft
                             this.lastFocusTime = System.currentTimeMillis();
                         }
                     }
-                    this.sndManager.setMuted(this.gameSettings.muteOnLostFocus.value && !this.gameWindow.isFocused());
+                    this.sndManager.setMuted(GameSettings.MUTE_ON_LOST_FOCUS.value && !this.gameWindow.isFocused());
 
                     switch (this.downloadResourcesThread.downloading) {
                         case DOWNLOADING: {
@@ -1122,7 +1115,7 @@ public class Minecraft
 
                     Debug.pop();    // 2
                     Debug.pop();    // 1
-                    if (this.gameSettings.showFrameTimes.value) {
+                    if (GameSettings.SHOW_FRAME_TIMES.value) {
                         DebugRender.render(this.font);
                     }
 
@@ -1151,6 +1144,12 @@ public class Minecraft
         } finally {
             shutdownMinecraftApplet();
         }
+        if (this.hasCrashed) {
+            LOGGER.error("--------------------==========##########==========--------------------");
+            LOGGER.error("                  Better than Adventure has crashed!                  ");
+            LOGGER.error("      Please report this to https://bugs.betterthanadventure.net      ");
+            LOGGER.error("--------------------==========##########==========--------------------");
+        }
     }
 
     public void freeUpMemory() {
@@ -1168,7 +1167,7 @@ public class Minecraft
     }
 
     private void screenshotListener() {
-        if (this.gameSettings.keyScreenshot.isPressed()) {
+        if (GameSettings.KEY_SCREENSHOT.isPressed()) {
             if (!this.isTakingScreenshot) {
                 this.isTakingScreenshot = true;
 
@@ -1256,7 +1255,7 @@ public class Minecraft
         boolean flag = true;
         if (this.objectMouseOver == null) {
             bridge:
-            if (this.gameSettings.easyBridge.value) {
+            if (GameSettings.EASY_BRIDGE.value) {
                 if (clickType == 1) {
                     if (this.thePlayer.xRot < 45) {
                         break bridge;
@@ -1351,7 +1350,7 @@ public class Minecraft
     }
 
     public void resize() {
-        this.resolution.setScale(this.gameSettings.guiScale.value);
+        this.resolution.setScale(GameSettings.GUI_SCALE.value);
         if (this.currentScreen != null) {
             this.currentScreen.opened(this.resolution.getScaledWidthScreenCoords(), this.resolution.getScaledHeightScreenCoords());
         }
@@ -1452,16 +1451,16 @@ public class Minecraft
                         if (this.thePlayer.noPhysics && this.toggleFlyPressed) {
                             final float steps = 20;
 
-                            int step = Math.round(this.gameSettings.flightSpeed.value * steps);
+                            int step = Math.round(GameSettings.FLIGHT_SPEED.value * steps);
                             step += MathHelper.clamp(scrollDelta, -1, 1);
                             float newSpeed = step / steps;
                             newSpeed = MathHelper.clamp(newSpeed, 0.0f, 5.0f);
 
-                            this.gameSettings.flightSpeed.value = newSpeed;
+                            GameSettings.FLIGHT_SPEED.value = newSpeed;
 
                             this.thePlayer.setFlySpeed(newSpeed);
-                            this.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(this.gameSettings.flightSpeed);
-                        } else if (!this.gameSettings.keyZoom.isPressed()) {
+                            this.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(GameSettings.FLIGHT_SPEED);
+                        } else if (!GameSettings.KEY_ZOOM.isPressed()) {
                             this.thePlayer.inventory.changeCurrentSlot(scrollDelta);
                         }
                     }
@@ -1477,14 +1476,14 @@ public class Minecraft
                 }
                 this.thePlayer.input.keyEvent(-1, Mouse.getEventButton(), Mouse.getEventButtonState());
             }
-            if (this.toggleFlyPressed && !this.gameSettings.keyFly.isPressed()) {
+            if (this.toggleFlyPressed && !GameSettings.KEY_FLY.isPressed()) {
                 this.toggleFlyPressed = false;
                 if (this.flyPressedTime + 400 > System.currentTimeMillis()) {
                     this.thePlayer.setNoclip(!this.thePlayer.noPhysics);
                 }
             }
             while (Keyboard.next()) {
-                if (Keyboard.getEventKeyState() && this.gameSettings.showFrameTimes.value && DebugRender.keyPressed(Keyboard.getEventKey())) {
+                if (Keyboard.getEventKeyState() && GameSettings.SHOW_FRAME_TIMES.value && DebugRender.keyPressed(Keyboard.getEventKey())) {
                     continue;
                 }
 
@@ -1497,19 +1496,19 @@ public class Minecraft
                 boolean shift = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT);
                 //Fix your keyboard Mak you broke the overlay toggle
                 boolean control = Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL) /* || Keyboard.isKeyDown(Keyboard.KEY_F4)*/;
-                if (!(Keyboard.getEventKeyState() && this.gameSettings.keyToggleDebug.isPressed())) {
+                if (!(Keyboard.getEventKeyState() && GameSettings.KEY_TOGGLE_DEBUG.isPressed())) {
                     this.thePlayer.input.keyEvent(Keyboard.getEventKey(), -1, Keyboard.getEventKeyState());
                 }
 
-                if (this.gameSettings.keyToggleDebug.isPressEvent()) {
+                if (GameSettings.KEY_TOGGLE_DEBUG.isPressEvent()) {
                     this.f3Press = true;
                 }
-                if (this.gameSettings.keyToggleDebug.isReleaseEvent()) {
+                if (GameSettings.KEY_TOGGLE_DEBUG.isReleaseEvent()) {
                     if (this.f3Press) {
                         if (control) {
-                            this.gameSettings.showFrameTimes.toggle();
+                            GameSettings.SHOW_FRAME_TIMES.toggle();
                         } else {
-                            this.gameSettings.showDebugScreen.toggle();
+                            GameSettings.SHOW_DEBUG_SCREEN.toggle();
                         }
 
                         this.f3Press = false;
@@ -1517,32 +1516,32 @@ public class Minecraft
                 }
 
                 if (Keyboard.getEventKeyState()) {
-                    if (this.gameSettings.keyFullScreen.isPressEvent()) {
+                    if (GameSettings.KEY_FULL_SCREEN.isPressEvent()) {
                         this.gameWindow.toggleFullscreen();
                     } else {
-                        if (this.gameSettings.keyToggleDebug.isPressed()) {
+                        if (GameSettings.KEY_TOGGLE_DEBUG.isPressed()) {
                             if (Keyboard.getEventKey() == Keyboard.KEY_Q) {
                                 this.hudIngame.addChatMessage(TextFormatting.YELLOW + "Keyboard shortcuts: ");
-                                this.gameSettings.debugsKeys.sort(Comparator.comparing(KeyBinding::getKeyName));
-                                for (KeyBinding binding : this.gameSettings.debugsKeys) {
-                                    this.hudIngame.addChatMessage(String.format("%s + %s: %s", this.gameSettings.keyToggleDebug.getKeyName(), binding.getKeyName(), I18n.getInstance().translateKey(binding.getId())));
+                                GameSettings.DEBUG_KEYS.sort(Comparator.comparing(KeyBinding::getKeyName));
+                                for (KeyBinding binding : GameSettings.DEBUG_KEYS) {
+                                    this.hudIngame.addChatMessage(String.format("%s + %s: %s", GameSettings.KEY_TOGGLE_DEBUG.getKeyName(), binding.getKeyName(), I18n.getInstance().translateKey(binding.getId())));
                                 }
-                                this.hudIngame.addChatMessage(String.format("%s: %s", this.gameSettings.keyToggleTextureAtlas.getKeyName(), I18n.getInstance().translateKey(this.gameSettings.keyToggleTextureAtlas.getId())));
-                                this.hudIngame.addChatMessage(String.format("%s: %s", this.gameSettings.keyReleaseCursor.getKeyName(), I18n.getInstance().translateKey(this.gameSettings.keyReleaseCursor.getId())));
+                                this.hudIngame.addChatMessage(String.format("%s: %s", GameSettings.KEY_TOGGLE_TEXTURE_ATLAS.getKeyName(), I18n.getInstance().translateKey(GameSettings.KEY_TOGGLE_TEXTURE_ATLAS.getId())));
+                                this.hudIngame.addChatMessage(String.format("%s: %s", GameSettings.KEY_RELEASE_CURSOR.getKeyName(), I18n.getInstance().translateKey(GameSettings.KEY_RELEASE_CURSOR.getId())));
                             }
-                            if (this.gameSettings.keyReload.isPressEvent()) {
+                            if (GameSettings.KEY_RELOAD.isPressEvent()) {
                                 forceReload();
-                            } else if (this.gameSettings.keySwitchGamemode.isPressEvent()) {
+                            } else if (GameSettings.KEY_SWITCH_GAMEMODE.isPressEvent()) {
                                 if (this.currentWorld.getLevelData().getCheatsEnabled() || this.currentWorld.isClientSide) {
                                     if (this.thePlayer.getGamemode() == Gamemodes.CREATIVE) {
-                                        this.thePlayer.sendChatMessage("/gamemode 0");
+                                        this.thePlayer.sendChatMessage("/gamemode survival");
                                     } else {
-                                        this.thePlayer.sendChatMessage("/gamemode 1");
+                                        this.thePlayer.sendChatMessage("/gamemode creative");
                                     }
                                 }
-                            } else if (this.gameSettings.keyDumpTextures.isPressEvent()) {
+                            } else if (GameSettings.KEY_DUMP_TEXTURES.isPressEvent()) {
                                 Textures.dumpTextures();
-                            } else if (this.gameSettings.keyFullbright.isPressEvent()) {
+                            } else if (GameSettings.KEY_FULLBRIGHT.isPressEvent()) {
                                 PacketHandlerClient queue = getSendQueue();
 
                                 if (queue != null) {
@@ -1556,43 +1555,43 @@ public class Minecraft
                                     }
                                 }
                                 this.hudIngame.heldItemTooltipElement.setString("Fullbright: " + (this.fullbright ? "On" : "Off"));
-                            } else if (this.gameSettings.keyLightmaps.isPressEvent()) {
-                                if (this.gameSettings.lightmapStyle.value == LightmapStyle.COLORIZED) {
-                                    this.gameSettings.lightmapStyle.value = LightmapStyle.GRAY;
+                            } else if (GameSettings.KEY_LIGHTMAPS.isPressEvent()) {
+                                if (GameSettings.LIGHTMAP_STYLE.value == LightmapStyle.COLORIZED) {
+                                    GameSettings.LIGHTMAP_STYLE.value = LightmapStyle.GRAY;
                                     this.hudIngame.heldItemTooltipElement.setString("Lightmap: Gray");
                                 } else {
-                                    this.gameSettings.lightmapStyle.value = LightmapStyle.COLORIZED;
+                                    GameSettings.LIGHTMAP_STYLE.value = LightmapStyle.COLORIZED;
                                     this.hudIngame.heldItemTooltipElement.setString("Lightmap: Colored");
                                 }
-                            } else if (this.gameSettings.keyCollisionBoxes.isPressEvent()) {
-                                this.gameSettings.showCollisionBoxes.toggle();
-                                this.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(this.gameSettings.showCollisionBoxes);
-                            } else if (this.gameSettings.keyChunkBorders.isPressEvent()) {
-                                this.gameSettings.showChunkBorders.toggle();
-                                this.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(this.gameSettings.showChunkBorders);
-                            } else if (this.gameSettings.keyClearChat.isPressEvent()) {
+                            } else if (GameSettings.KEY_COLLISION_BOXES.isPressEvent()) {
+                                GameSettings.SHOW_COLLISION_BOXES.toggle();
+                                this.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(GameSettings.SHOW_COLLISION_BOXES);
+                            } else if (GameSettings.KEY_CHUNK_BORDERS.isPressEvent()) {
+                                GameSettings.SHOW_CHUNK_BORDERS.toggle();
+                                this.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(GameSettings.SHOW_CHUNK_BORDERS);
+                            } else if (GameSettings.KEY_CLEAR_CHAT.isPressEvent()) {
                                 this.hudIngame.clearChatMessages();
-                            } else if (this.gameSettings.keyPauseLostFocus.isPressEvent()) {
-                                this.gameSettings.pauseOnLostFocus.toggle();
-                                this.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(this.gameSettings.pauseOnLostFocus);
-                            } else if (this.gameSettings.keyToggleItemInfo.isPressEvent()) {
-                                this.gameSettings.showItemDebugInfo.toggle();
-                                this.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(this.gameSettings.showItemDebugInfo);
-                            } else if (this.gameSettings.keyReloadChunks.isPressEvent()) {
+                            } else if (GameSettings.KEY_PAUSE_LOST_FOCUS.isPressEvent()) {
+                                GameSettings.PAUSE_ON_LOST_FOCUS.toggle();
+                                this.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(GameSettings.PAUSE_ON_LOST_FOCUS);
+                            } else if (GameSettings.KEY_TOGGLE_ITEM_INFO.isPressEvent()) {
+                                GameSettings.SHOW_ITEM_DEBUG_INFO.toggle();
+                                this.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(GameSettings.SHOW_ITEM_DEBUG_INFO);
+                            } else if (GameSettings.KEY_RELOAD_CHUNKS.isPressEvent()) {
                                 this.renderGlobal.allChanged();
-                            } else if (this.gameSettings.keySmoothLighting.isPressEvent()) {
-                                this.gameSettings.ambientOcclusion.toggle();
-                                this.gameSettings.ambientOcclusion.onUpdate();
-                                this.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(this.gameSettings.ambientOcclusion);
+                            } else if (GameSettings.KEY_SMOOTH_LIGHTING.isPressEvent()) {
+                                GameSettings.AMBIENT_OCCLUSION.toggle();
+                                GameSettings.AMBIENT_OCCLUSION.onUpdate();
+                                this.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(GameSettings.AMBIENT_OCCLUSION);
                             }
-                            if (!this.gameSettings.keyToggleDebug.isPressEvent()) this.f3Press = false;
-                        } else if (this.gameSettings.keyReleaseCursor.isPressEvent()) {
+                            if (!GameSettings.KEY_TOGGLE_DEBUG.isPressEvent()) this.f3Press = false;
+                        } else if (GameSettings.KEY_RELEASE_CURSOR.isPressEvent()) {
                             this.mouseInput.releaseCursor();
-                        } else if (this.gameSettings.keyShowConsole.isPressEvent() && this.gameSettings.developerMode.value) {
+                        } else if (GameSettings.KEY_SHOW_CONSOLE.isPressEvent() && GameSettings.DEVELOPER_MODE.value) {
                             displayScreen(new ScreenConsole(this.currentScreen));
                         } else if (Keyboard.getEventKey() == Keyboard.KEY_ESCAPE) {
                             displayInGameMenu();
-                        } else if (this.gameSettings.keyCommand.isPressed()) {
+                        } else if (GameSettings.KEY_COMMAND.isPressed()) {
                             displayScreen(new ScreenChat("/"));
                         } else {
                             checkBoundInputs(InputDevice.keyboard);
@@ -1603,14 +1602,14 @@ public class Minecraft
                 }
             }
 
-            boolean breakBlockPressed = this.gameSettings.keyAttack.isPressed() || (this.controllerInput != null && this.controllerInput.buttonRightTrigger.isPressed());
-            boolean placeBlockPressed = this.gameSettings.keyInteract.isPressed() || (this.controllerInput != null && this.controllerInput.buttonLeftTrigger.isPressed());
+            boolean breakBlockPressed = GameSettings.KEY_ATTACK.isPressed() || (this.controllerInput != null && this.controllerInput.buttonRightTrigger.isPressed());
+            boolean placeBlockPressed = GameSettings.KEY_INTERACT.isPressed() || (this.controllerInput != null && this.controllerInput.buttonLeftTrigger.isPressed());
 
             if (this.currentScreen == null) {
                 if (breakBlockPressed && (float) (this.ticksRan - this.mouseTicksRan) >= this.timer.ticksPerSecond / 5F && this.inGameHasFocus)
-                    clickMouse(0, this.gameSettings.autoHit.value, true);
+                    clickMouse(0, GameSettings.AUTO_HIT.value, true);
                 if (placeBlockPressed && (float) (this.ticksRan - this.mouseTicksRan) >= this.timer.ticksPerSecond / 5F && this.inGameHasFocus)
-                    clickMouse(1, this.gameSettings.autoHit.value, true);
+                    clickMouse(1, GameSettings.AUTO_HIT.value, true);
             }
             mineBlocks(this.currentScreen == null && breakBlockPressed && this.inGameHasFocus);
         }
@@ -1626,9 +1625,9 @@ public class Minecraft
                     this.joinPlayerCounter = 0;
                     this.currentWorld.joinEntityInSurroundings(this.thePlayer);
                 }
-                this.thePlayer.setFlySpeed(this.gameSettings.flightSpeed.value);
-                this.thePlayer.setFlightSmoothness(this.gameSettings.flightSmoothness.value);
-                this.thePlayer.turnWithVehicle = this.gameSettings.turnWithVehicle.value;
+                this.thePlayer.setFlySpeed(GameSettings.FLIGHT_SPEED.value);
+                this.thePlayer.setFlightSmoothness(GameSettings.FLIGHT_SMOOTHNESS.value);
+                this.thePlayer.turnWithVehicle = GameSettings.TURN_WITH_VEHICLE.value;
             }
             if (!this.isGamePaused) {
                 this.worldRenderer.updateRenderer();
@@ -1693,38 +1692,38 @@ public class Minecraft
         boolean control = Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL);
 
         // Attack
-        if (this.gameSettings.keyAttack.isPressEvent(currentInputDevice)) {
+        if (GameSettings.KEY_ATTACK.isPressEvent(currentInputDevice)) {
             clickMouse(0, true, false);
             return true;
         }
 
         // Interact
-        if (this.gameSettings.keyInteract.isPressEvent(currentInputDevice)) {
+        if (GameSettings.KEY_INTERACT.isPressEvent(currentInputDevice)) {
             clickMouse(1, true, false);
             return true;
         }
 
         // Pick block
-        if (this.gameSettings.keyPickBlock.isPressEvent(currentInputDevice)) {
+        if (GameSettings.KEY_PICK_BLOCK.isPressEvent(currentInputDevice)) {
             clickMiddleMouseButton(shift, control);
             return true;
         }
 
         // Toggle overlay
-        if (this.gameSettings.keyToggleOverlay.isPressEvent(currentInputDevice)) {
+        if (GameSettings.KEY_TOGGLE_OVERLAY.isPressEvent(currentInputDevice)) {
             if (control) {
-                this.gameSettings.overlayMode.value++;
-                this.gameSettings.overlayMode.value %= 3;
+                GameSettings.OVERLAY_MODE.value++;
+                GameSettings.OVERLAY_MODE.value %= 3;
             } else {
                 boolean on = false;
-                for (int i = 0; i < this.gameSettings.overlayElements.length; i++) {
-                    if (this.gameSettings.overlayElements[i].value) {
+                for (int i = 0; i < GameSettings.OVERLAY_ELEMENTS.length; i++) {
+                    if (GameSettings.OVERLAY_ELEMENTS[i].value) {
                         on = true;
                         break;
                     }
                 }
-                for (int i = 0; i < this.gameSettings.overlayElements.length; i++) {
-                    this.gameSettings.overlayElements[i].value = !on;
+                for (int i = 0; i < GameSettings.OVERLAY_ELEMENTS.length; i++) {
+                    GameSettings.OVERLAY_ELEMENTS[i].value = !on;
                 }
             }
 
@@ -1732,74 +1731,74 @@ public class Minecraft
         }
 
         // Hide GUI
-        if (this.gameSettings.keyHideGui.isPressEvent(currentInputDevice)) {
-            this.gameSettings.immersiveMode.toggle();
+        if (GameSettings.KEY_HIDE_GUI.isPressEvent(currentInputDevice)) {
+            GameSettings.IMMERSIVE_MODE.toggle();
             return true;
         }
 
         // Switch perspective
-        if (this.gameSettings.keySwitchPerspective.isPressEvent(currentInputDevice)) {
-            this.gameSettings.thirdPersonView.value = (this.gameSettings.thirdPersonView.value + 1) % 3;
+        if (GameSettings.KEY_SWITCH_PERSPECTIVE.isPressEvent(currentInputDevice)) {
+            GameSettings.THIRD_PERSON_VIEW.value = (GameSettings.THIRD_PERSON_VIEW.value + 1) % 3;
             return true;
         }
 
         // Cinematic camera
-        if (this.gameSettings.keyCinematicCamera.isPressEvent(currentInputDevice)) {
-            this.gameSettings.smoothCamera.value = !this.gameSettings.smoothCamera.value;
-            this.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(this.gameSettings.smoothCamera);
+        if (GameSettings.KEY_CINEMATIC_CAMERA.isPressEvent(currentInputDevice)) {
+            GameSettings.SMOOTH_CAMERA.value = !GameSettings.SMOOTH_CAMERA.value;
+            this.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(GameSettings.SMOOTH_CAMERA);
             return true;
         }
 
         // Display inventory
-        if (this.gameSettings.keyInventory.isPressEvent(currentInputDevice)) {
+        if (GameSettings.KEY_INVENTORY.isPressEvent(currentInputDevice)) {
             displayScreen(getInventoryScreen());
             return true;
         }
 
         // Display Guidebook
-        if (this.gameSettings.keyGuidebook.isPressEvent(currentInputDevice)) {
+        if (GameSettings.KEY_GUIDEBOOK.isPressEvent(currentInputDevice)) {
             this.thePlayer.displayGuidebookScreen();
             return true;
         }
 
         // Drop item
-        if (this.gameSettings.keyDrop.isPressEvent(currentInputDevice)) {
+        if (GameSettings.KEY_DROP.isPressEvent(currentInputDevice)) {
             this.thePlayer.dropCurrentItem(control);
             return true;
         }
 
         // Enter photo mode
-        if (this.gameSettings.keyPhotoMode.isPressEvent(currentInputDevice)) {
+        if (GameSettings.KEY_PHOTO_MODE.isPressEvent(currentInputDevice)) {
             displayScreen(new ScreenPhotoMode());
             return true;
         }
 
         // Open chat
-        if (this.gameSettings.keyChat.isPressEvent(currentInputDevice)) {
+        if (GameSettings.KEY_CHAT.isPressEvent(currentInputDevice)) {
             displayScreen(new ScreenChat());
             return true;
         }
 
         // Show player list
-        if (isMultiplayerWorld() && this.gameSettings.keyPlayerList.isPressEvent(currentInputDevice)) {
+        if (isMultiplayerWorld() && GameSettings.KEY_PLAYER_LIST.isPressEvent(currentInputDevice)) {
             if (control) {
-                this.gameSettings.playerListPosition.value++;
-                this.gameSettings.playerListPosition.value %= 3;
+                GameSettings.PLAYER_LIST_POSITION.value++;
+                GameSettings.PLAYER_LIST_POSITION.value %= 3;
             } else {
-                this.gameSettings.showPlayerList.value = !this.gameSettings.showPlayerList.value;
+                GameSettings.SHOW_PLAYER_LIST.value = !GameSettings.SHOW_PLAYER_LIST.value;
             }
             return true;
         }
 
         // Fly
-        if (this.thePlayer.getGamemode().hasPlayerFlight() && this.gameSettings.keyFly.isPressEvent(currentInputDevice)) {
+        if (this.thePlayer.getGamemode().hasPlayerFlight() && GameSettings.KEY_FLY.isPressEvent(currentInputDevice)) {
             if (!this.toggleFlyPressed) this.toggleFlyPressed = true;
             this.flyPressedTime = System.currentTimeMillis();
             return true;
         }
 
         // Hotbar switch
-        if (this.gameSettings.keyHotBarSwitch.isPressEvent(currentInputDevice)) {
+        if (GameSettings.KEY_HOT_BAR_SWITCH.isPressEvent(currentInputDevice)) {
             if (!this.thePlayer.inventory.currentSlotLocked()) {
                 if (shift) {
                     this.thePlayer.setHotbarOffset((this.thePlayer.inventory.getHotbarOffset() + 27) % (36));
@@ -1814,16 +1813,16 @@ public class Minecraft
         }
 
         // Center view
-        if (this.gameSettings.keyCenterView.isPressEvent(currentInputDevice)) {
+        if (GameSettings.KEY_CENTER_VIEW.isPressEvent(currentInputDevice)) {
             this.thePlayer.xRot = 0.0f;
             return true;
         }
 
         // Lock rotation
-        if (this.gameSettings.keyLockRotation.isPressEvent(currentInputDevice)) {
+        if (GameSettings.KEY_LOCK_ROTATION.isPressEvent(currentInputDevice)) {
             if (control) {
-                this.gameSettings.rotationOverlayMode.value++;
-                this.gameSettings.rotationOverlayMode.value %= 4;
+                GameSettings.ROTATION_OVERLAY_MODE.value++;
+                GameSettings.ROTATION_OVERLAY_MODE.value %= 4;
             } else {
                 if (this.thePlayer.rotationLock == null || this.thePlayer.rotationLock == Direction.NONE) {
                     this.thePlayer.rotationLock = Direction.getDirection(this.thePlayer);
@@ -1840,73 +1839,73 @@ public class Minecraft
         }
 
         // Toggle fog
-        if (this.gameSettings.keyToggleFog.isPressEvent(currentInputDevice)) {
-            int renderDistance = this.gameSettings.renderDistance.value;
+        if (GameSettings.KEY_TOGGLE_FOG.isPressEvent(currentInputDevice)) {
+            int renderDistance = GameSettings.RENDER_DISTANCE.value;
             int nextRenderDistance;
             if (!shift) {
                 nextRenderDistance = renderDistance / 8 * 8 + 8;
             } else {
                 nextRenderDistance = (renderDistance - 1) / 8 * 8;
             }
-            if (nextRenderDistance > this.gameSettings.renderDistance.highest && !shift) {
-                nextRenderDistance = this.gameSettings.renderDistance.highest;
+            if (nextRenderDistance > GameSettings.RENDER_DISTANCE.highest && !shift) {
+                nextRenderDistance = GameSettings.RENDER_DISTANCE.highest;
             }
-            if (nextRenderDistance < this.gameSettings.renderDistance.lowest && shift) {
-                nextRenderDistance = this.gameSettings.renderDistance.lowest;
+            if (nextRenderDistance < GameSettings.RENDER_DISTANCE.lowest && shift) {
+                nextRenderDistance = GameSettings.RENDER_DISTANCE.lowest;
             }
-            if (renderDistance == this.gameSettings.renderDistance.highest && !shift) {
-                nextRenderDistance = this.gameSettings.renderDistance.lowest;
+            if (renderDistance == GameSettings.RENDER_DISTANCE.highest && !shift) {
+                nextRenderDistance = GameSettings.RENDER_DISTANCE.lowest;
             }
-            if (renderDistance == this.gameSettings.renderDistance.lowest && shift) {
-                nextRenderDistance = this.gameSettings.renderDistance.highest;
+            if (renderDistance == GameSettings.RENDER_DISTANCE.lowest && shift) {
+                nextRenderDistance = GameSettings.RENDER_DISTANCE.highest;
             }
 
-            this.gameSettings.renderDistance.set(nextRenderDistance);
-            this.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(this.gameSettings.renderDistance);
+            GameSettings.RENDER_DISTANCE.set(nextRenderDistance);
+            this.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(GameSettings.RENDER_DISTANCE);
             return true;
         }
 
         // Toggle gamma
-        if (this.gameSettings.keyToggleGamma.isPressEvent(currentInputDevice)) {
+        if (GameSettings.KEY_TOGGLE_GAMMA.isPressEvent(currentInputDevice)) {
             int currentGammaStep = 2;
-            if (this.gameSettings.gamma.value < 0.125f) {
+            if (GameSettings.GAMMA.value < 0.125f) {
                 currentGammaStep = 0;
-            } else if (this.gameSettings.gamma.value < 0.375f) {
+            } else if (GameSettings.GAMMA.value < 0.375f) {
                 currentGammaStep = 1;
-            } else if (this.gameSettings.gamma.value > 0.875f) {
+            } else if (GameSettings.GAMMA.value > 0.875f) {
                 currentGammaStep = 4;
-            } else if (this.gameSettings.gamma.value > 0.625f) {
+            } else if (GameSettings.GAMMA.value > 0.625f) {
                 currentGammaStep = 3;
             }
             int newGammaStep = ((currentGammaStep + (shift ? -1 : 1)) + 5) % 5;
-            this.gameSettings.gamma.value = newGammaStep * 0.25f;
-            this.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(this.gameSettings.gamma);
+            GameSettings.GAMMA.value = newGammaStep * 0.25f;
+            this.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(GameSettings.GAMMA);
             return true;
         }
 
         // Hotbar left
-        if (this.gameSettings.keyHotBarLeft.isPressEvent(currentInputDevice)) {
+        if (GameSettings.KEY_HOT_BAR_LEFT.isPressEvent(currentInputDevice)) {
             this.thePlayer.inventory.changeCurrentSlot(1);
             return true;
         }
 
         // Hotbar right
-        if (this.gameSettings.keyHotBarRight.isPressEvent(currentInputDevice)) {
+        if (GameSettings.KEY_HOT_BAR_RIGHT.isPressEvent(currentInputDevice)) {
             this.thePlayer.inventory.changeCurrentSlot(-1);
             return true;
         }
 
         // Hotbar slots
         KeyBinding[] hotbarSlots = new KeyBinding[]{
-            this.gameSettings.keyHotBarSlot1,
-            this.gameSettings.keyHotBarSlot2,
-            this.gameSettings.keyHotBarSlot3,
-            this.gameSettings.keyHotBarSlot4,
-            this.gameSettings.keyHotBarSlot5,
-            this.gameSettings.keyHotBarSlot6,
-            this.gameSettings.keyHotBarSlot7,
-            this.gameSettings.keyHotBarSlot8,
-            this.gameSettings.keyHotBarSlot9
+            GameSettings.KEY_HOT_BAR_SLOT_1,
+            GameSettings.KEY_HOT_BAR_SLOT_2,
+            GameSettings.KEY_HOT_BAR_SLOT_3,
+            GameSettings.KEY_HOT_BAR_SLOT_4,
+            GameSettings.KEY_HOT_BAR_SLOT_5,
+            GameSettings.KEY_HOT_BAR_SLOT_6,
+            GameSettings.KEY_HOT_BAR_SLOT_7,
+            GameSettings.KEY_HOT_BAR_SLOT_8,
+            GameSettings.KEY_HOT_BAR_SLOT_9
         };
         for (int i = 0; i < hotbarSlots.length; i++) {
             if (hotbarSlots[i].isPressEvent(currentInputDevice)) {
@@ -1916,23 +1915,23 @@ public class Minecraft
         }
 
         // Zoom
-        if (this.gameSettings.keyZoom.isPressEvent(currentInputDevice)) {
+        if (GameSettings.KEY_ZOOM.isPressEvent(currentInputDevice)) {
             Mouse.getDWheel(); // This resets the mouse delta before its checked by zoom, fixes a bug please don't remove
             this.worldRenderer.zooming = true;
             return true;
         }
-        if (this.gameSettings.keyZoom.isReleaseEvent(currentInputDevice)) {
+        if (GameSettings.KEY_ZOOM.isReleaseEvent(currentInputDevice)) {
             this.worldRenderer.zooming = false;
             return true;
         }
 
         // Open Achievements
-        if (this.gameSettings.keyOpenAchievements.isPressEvent(currentInputDevice)) {
+        if (GameSettings.KEY_OPEN_ACHIEVEMENTS.isPressEvent(currentInputDevice)) {
             displayScreen(new ScreenAchievements(null, this.statsCounter));
         }
 
         // Open Statistics
-        if (this.gameSettings.keyOpenStatistics.isPressEvent(currentInputDevice)) {
+        if (GameSettings.KEY_OPEN_STATISTICS.isPressEvent(currentInputDevice)) {
             displayScreen(new ScreenStats(null, this.statsCounter));
         }
 
@@ -1983,7 +1982,7 @@ public class Minecraft
                 displayScreen(getInventoryScreen());
             }
             if (controller.buttonBack.pressedThisFrame()) {
-                this.gameSettings.showPlayerList.value = !this.gameSettings.showPlayerList.value;
+                GameSettings.SHOW_PLAYER_LIST.value = !GameSettings.SHOW_PLAYER_LIST.value;
             }
             if (controller.buttonStart.pressedThisFrame()) {
                 displayScreen(new ScreenPause());
@@ -2012,8 +2011,8 @@ public class Minecraft
                 this.thePlayer.inventory.changeCurrentSlot(-1);
             }
             if (controller.joyLeft.getButton().pressedThisFrame()) {
-                this.gameSettings.thirdPersonView.value++;
-                this.gameSettings.thirdPersonView.value %= 3;
+                GameSettings.THIRD_PERSON_VIEW.value++;
+                GameSettings.THIRD_PERSON_VIEW.value %= 3;
             }
             if (this.controllerInput.digitalPad.right.pressedThisFrame()) {
                 this.thePlayer.displayGuidebookScreen();
@@ -2030,9 +2029,9 @@ public class Minecraft
     private void forceReload() {
         long start = System.nanoTime();
         LOGGER.info("FORCING RELOAD!");
-        I18n.getInstance().reload(this.gameSettings.language.value);
+        I18n.getInstance().reload(GameSettings.LANGUAGE.value);
         this.sndManager = new SoundEngine();
-        this.sndManager.init(this.gameSettings);
+        this.sndManager.init();
         this.texturePackList.refresh();
         this.renderer.reload();
         Shaders.reload();
@@ -2061,10 +2060,11 @@ public class Minecraft
             worldConfiguration.getFinalWorldName(),
             worldConfiguration.getFinalNumericSeed(),
             Dimension.OVERWORLD,
-            null
+            null, worldConfiguration.getStartingBiome()
         );
         world.getLevelData().setCheatsEnabled(worldConfiguration.getCheatsEnabled());
         world.getLevelData().getGameRules().setValues(worldConfiguration.getGameRuleCollection());
+        world.getSpawnerConfig().set(worldConfiguration.getSpawnerConfig());
 
         this.statsCounter.add(StatList.createWorldStat, 1);
         this.statsCounter.add(StatList.startGameStat, 1);
@@ -2103,7 +2103,7 @@ public class Minecraft
                 dimension = Dimension.getDimensionList().get(tag.getInteger("Dimension"));
             }
 
-            WorldClient world = new WorldClient(saveHandler, null, 0L, dimension, null);
+            WorldClient world = new WorldClient(saveHandler, null, 0L, dimension, null, null);
             this.statsCounter.add(StatList.loadWorldStat, 1);
             this.statsCounter.add(StatList.startGameStat, 1);
             changeWorld(world, i18n.translateKey("gui.loading.label.loading"));
@@ -2165,7 +2165,7 @@ public class Minecraft
 
     public void changeWorld(WorldClient world, String loadingTitle, @Nullable Player player) {
         this.mainMenuBackground.deleteTextures();
-        this.gameSettings.showCollisionBoxes.value = false;
+        GameSettings.SHOW_COLLISION_BOXES.value = false;
 
         this.fullbright = false;
         this.statsCounter.fetchStats();
@@ -2620,15 +2620,15 @@ public class Minecraft
     }
 
     public boolean isAmbientOcclusionEnabled() {
-        return this.gameSettings.ambientOcclusion.value;
+        return GameSettings.AMBIENT_OCCLUSION.value;
     }
 
     public boolean isTreeShadingEnabled() {
-        return this.gameSettings.treeShadows.value;
+        return GameSettings.TREE_SHADOWS.value;
     }
 
     public boolean isDebugInfoEnabled() {
-        return this.gameSettings.showDebugScreen.value;
+        return GameSettings.SHOW_DEBUG_SCREEN.value;
     }
 
     @Override
@@ -2641,12 +2641,12 @@ public class Minecraft
     }
 
     public float getOutlineWidth() {
-        return INSTANCE.gameSettings.blockOutlineWidth.value;
+        return GameSettings.BLOCK_OUTLINE_WIDTH.value;
     }
 
     public int getAutosaveTimer() {
 
-        return (int) (INSTANCE.gameSettings.autosaveTimer.value * 24) * 5;
+        return (int) (GameSettings.AUTOSAVE_TIMER.value * 24) * 5;
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/discord/RichPresenceHandlerThread.java b/game/client/src/main/java/net/minecraft/client/discord/RichPresenceHandlerThread.java
index 6076e74e4..03eff517c 100644
--- a/game/client/src/main/java/net/minecraft/client/discord/RichPresenceHandlerThread.java
+++ b/game/client/src/main/java/net/minecraft/client/discord/RichPresenceHandlerThread.java
@@ -14,6 +14,7 @@ import de.jcm.discordgamesdk.activity.Activity;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.entity.player.PlayerLocalMultiplayer;
 import net.minecraft.client.gui.ScreenPause;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.biome.Biomes;
@@ -99,7 +100,7 @@ public class RichPresenceHandlerThread extends Thread {
         // Initialize the Core
         Core.init(discordLibrary);
 
-        startTime = Instant.now();
+        this.startTime = Instant.now();
 
         // Create the Activity
         updateActivity();
@@ -107,12 +108,12 @@ public class RichPresenceHandlerThread extends Thread {
         int counter = 0;
         // Run callbacks forever
         while (true) {
-            if (core != null) {
-                if (!hasRegistered) {
-                    core.activityManager().registerCommand("e");
-                    hasRegistered = true;
+            if (this.core != null) {
+                if (!this.hasRegistered) {
+                    this.core.activityManager().registerCommand("e");
+                    this.hasRegistered = true;
                 }
-                core.runCallbacks();
+                this.core.runCallbacks();
             }
             try {
                 // Sleep a bit to save CPU
@@ -129,40 +130,40 @@ public class RichPresenceHandlerThread extends Thread {
     }
 
     private void updateActivity() {
-        if (!minecraft.gameSettings.discordRichPresence.value) {
-            if (core != null) {
+        if (!GameSettings.DISCORD_RICH_PRESENCE.value) {
+            if (this.core != null) {
                 destroyCore();
             }
         } else {
-            if (core == null) {
+            if (this.core == null) {
                 createCore();
             }
         }
 
-        if (core == null) return;
+        if (this.core == null) return;
 
         Activity activity = new Activity();
         activity.assets().setLargeImage("bta-logo");
-        activity.timestamps().setStart(startTime);
+        activity.timestamps().setStart(this.startTime);
 
-        if (minecraft.currentWorld == null) {
+        if (this.minecraft.currentWorld == null) {
             activity.setState("In the main menu");
-        } else if (minecraft.thePlayer != null) {
-            if (minecraft.thePlayer instanceof PlayerLocalMultiplayer) {
+        } else if (this.minecraft.thePlayer != null) {
+            if (this.minecraft.thePlayer instanceof PlayerLocalMultiplayer) {
                 activity.setDetails("Multiplayer");
-                int playerCount = ((PlayerLocalMultiplayer) minecraft.thePlayer).sendQueue.players.size();
+                int playerCount = ((PlayerLocalMultiplayer) this.minecraft.thePlayer).sendQueue.players.size();
                 activity.party().size().setCurrentSize(playerCount);
                 activity.party().size().setMaxSize(100);
             } else {
-                if (minecraft.currentScreen instanceof ScreenPause) {
+                if (this.minecraft.currentScreen instanceof ScreenPause) {
                     activity.setDetails("Singleplayer (paused)");
                 } else {
                     activity.setDetails("Singleplayer");
                 }
             }
-            Dimension activeDimension = Dimension.getDimensionList().get(minecraft.thePlayer.dimension);
-            Biome biome = minecraft.currentWorld.getBlockBiome((int) minecraft.thePlayer.x, (int) minecraft.thePlayer.y, (int) minecraft.thePlayer.z);
-            Weather weather = minecraft.currentWorld.getCurrentWeather();
+            Dimension activeDimension = Dimension.getDimensionList().get(this.minecraft.thePlayer.dimension);
+            Biome biome = this.minecraft.currentWorld.getBlockBiome((int) this.minecraft.thePlayer.x, (int) this.minecraft.thePlayer.y, (int) this.minecraft.thePlayer.z);
+            Weather weather = this.minecraft.currentWorld.getCurrentWeather();
 
             boolean displayDimension = activeDimension != null && dimensionNamesMap.containsKey(activeDimension);
             boolean displayBiome = biome != null && biomeNamesMap.containsKey(biome);
@@ -187,7 +188,7 @@ public class RichPresenceHandlerThread extends Thread {
             activity.setState(stateString.toString());
 
         }
-        core.activityManager().updateActivity(activity);
+        this.core.activityManager().updateActivity(activity);
     }
 
     private void createCore() {
@@ -196,15 +197,15 @@ public class RichPresenceHandlerThread extends Thread {
             params.setClientID(clientId);
             params.setFlags(CreateParams.Flags.NO_REQUIRE_DISCORD);
             // Create the Core
-            core = new Core(params);
+            this.core = new Core(params);
         } catch (GameSDKException sdkException) {
             // Exception normally occurs only when discord is not opened on the client
-            core = null;
+            this.core = null;
         }
     }
 
     private void destroyCore() {
-        core.close();
-        core = null;
+        this.core.close();
+        this.core = null;
     }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/entity/ClientSkinVariantList.java b/game/client/src/main/java/net/minecraft/client/entity/ClientSkinVariantList.java
index a3720b658..04e024314 100644
--- a/game/client/src/main/java/net/minecraft/client/entity/ClientSkinVariantList.java
+++ b/game/client/src/main/java/net/minecraft/client/entity/ClientSkinVariantList.java
@@ -18,6 +18,7 @@ import com.mojang.logging.LogUtils;
 import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.core.entity.SkinVariantList;
 import net.minecraft.core.util.helper.MathHelper;
 import org.jetbrains.annotations.NotNull;
@@ -52,7 +53,7 @@ public class ClientSkinVariantList extends SkinVariantList {
 
 	protected @Nullable EntityVariants getEntityVariants(@Nullable final String variantJsonPath) {
 		try {
-			if (!Minecraft.getMinecraft().gameSettings.mobVariants.value) return null;
+			if (!GameSettings.MOB_VARIANTS.value) return null;
 			if (variantJsonPath == null) return null;
 			if (this.variantProcessorMap.containsKey(variantJsonPath)) {
 				return this.variantProcessorMap.get(variantJsonPath);
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 edfbae4ec..1a03d81b3 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
@@ -5,6 +5,8 @@ import com.mojang.logging.LogUtils;
 import com.mojang.nbt.tags.CompoundTag;
 
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
+import net.minecraft.client.option.enums.ParticlesQuality;
 import net.minecraft.client.render.particle.ParticlePickupAnimation;
 import net.minecraft.client.gui.container.*;
 import net.minecraft.client.gui.ScreenLabelEditor;
@@ -62,14 +64,16 @@ public class PlayerLocal extends Player {
         this.username = session.username;
         this.uuid = session.uuid;
 
-        this.playerConfig.setLeftHand(minecraft.gameSettings.playerLeftHanded.value);
-        this.playerConfig.setCape(minecraft.gameSettings.playerCape.value);
-        this.playerConfig.setHat(minecraft.gameSettings.playerHat.value);
-        this.playerConfig.setJacket(minecraft.gameSettings.playerJacket.value);
-        this.playerConfig.setSleeveLeft(minecraft.gameSettings.playerSleeveLeft.value);
-        this.playerConfig.setSleeveRight(minecraft.gameSettings.playerSleeveRight.value);
-        this.playerConfig.setPantLeft(minecraft.gameSettings.playerPantLeft.value);
-        this.playerConfig.setPantRight(minecraft.gameSettings.playerPantRight.value);
+        this.playerConfig.setLeftHand(GameSettings.PLAYER_LEFT_HANDED.value);
+        this.playerConfig.setCape(GameSettings.PLAYER_CAPE.value);
+        this.playerConfig.setHat(GameSettings.PLAYER_HAT.value);
+        this.playerConfig.setJacket(GameSettings.PLAYER_JACKET.value);
+        this.playerConfig.setSleeveLeft(GameSettings.PLAYER_SLEEVE_LEFT.value);
+        this.playerConfig.setSleeveRight(GameSettings.PLAYER_SLEEVE_RIGHT.value);
+        this.playerConfig.setPantLeft(GameSettings.PLAYER_PANT_LEFT.value);
+        this.playerConfig.setPantRight(GameSettings.PLAYER_PANT_RIGHT.value);
+        this.playerConfig.setDevModelEnabled(GameSettings.PLAYER_DEV_MODEL.value);
+        this.playerConfig.setHurtSound(GameSettings.PLAYER_HURT_SOUND.value);
 
         new GetSkinUrlThread(this);
         LOGGER.info("logged in with session name: {}", this.username);
@@ -192,7 +196,7 @@ public class PlayerLocal extends Player {
                 this.sprintTimer = 0;
             }
         }
-        if (this.onGround && canSprint && this.mc.gameSettings.keySprint.isPressed()) {
+        if (this.onGround && canSprint && GameSettings.KEY_SPRINT.isPressed()) {
             setSprinting(true);
         }
         if (isSprinting() && (this.input.moveForward < f || this.horizontalCollision || !canSprint)) {
@@ -311,6 +315,7 @@ public class PlayerLocal extends Player {
     @Override
     public void onItemPickup(Entity entity, ItemStack item) {
         addStat(item.getItem().getStat(StatList.STAT_PICKED_UP), 1);
+        if (GameSettings.PARTICLES_QUALITY.value == ParticlesQuality.NONE) return;
         this.mc.particleEngine.add(new ParticlePickupAnimation(this.mc.currentWorld, entity, this, -0.5F));
     }
 
@@ -379,7 +384,7 @@ public class PlayerLocal extends Player {
     }
 
     @Override
-    public void addStat(Stat stat, int i) {
+    public void addStat(@Nullable Stat stat, int i) {
         if (stat == null) {
             return;
         }
@@ -397,7 +402,7 @@ public class PlayerLocal extends Player {
     }
 
     @Override
-    public int getStat(Stat stat) {
+    public int getStat(@Nullable Stat stat) {
         return this.mc.statsCounter.readStat(stat);
     }
 
@@ -442,7 +447,7 @@ public class PlayerLocal extends Player {
     }
 
     public void syncPlacementMode() {
-        this.placementModeOverride = this.mc.gameSettings.placementMode.value;
+        this.placementModeOverride = GameSettings.PLACEMENT_MODE.value;
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ExceptionPopupElement.java b/game/client/src/main/java/net/minecraft/client/gui/ExceptionPopupElement.java
index 43f6dd3c9..153ae924e 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ExceptionPopupElement.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/ExceptionPopupElement.java
@@ -4,11 +4,11 @@ import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.popup.PopupScreen;
 import net.minecraft.client.gui.popup.PopupBuilder;
 import net.minecraft.client.gui.popup.PopupCloseListener;
+import net.minecraft.client.render.OpenGLHelper;
 import net.minecraft.core.Global;
 import net.minecraft.core.net.command.TextFormatting;
 import org.jetbrains.annotations.NotNull;
 import org.lwjgl.Sys;
-import org.lwjgl.opengl.GL41;
 
 import java.text.SimpleDateFormat;
 import java.util.Date;
@@ -17,7 +17,6 @@ import java.util.Map;
 public class ExceptionPopupElement {
 
     public static PopupScreen create(Screen parent, Throwable e, Minecraft mc) {
-        int scale = Math.max(mc.resolution.getScale(), 1);
         StringBuilder s = new StringBuilder("Minecraft ran into an unexpected problem!\n\n");
         s.append("To prevent more problems, the current game has quit, but you can try to keep playing.\n\n");
         s.append("If you wish to report this, please copy this entire text and post it on the support portal at")
@@ -31,7 +30,7 @@ public class ExceptionPopupElement {
             s.append("Java: ").append(System.getProperty("java.version")).append(", ").append(System.getProperty("java.vendor")).append("\n");
             s.append("VM: ").append(System.getProperty("java.vm.name")).append(" (").append(System.getProperty("java.vm.info")).append("), ").append(System.getProperty("java.vm.vendor")).append("\n");
             s.append("LWJGL: ").append(Sys.getVersion()).append("\n");
-            s.append("OpenGL: ").append(GL41.glGetString(GL41.GL_RENDERER)).append(" version ").append(GL41.glGetString(GL41.GL_VERSION)).append(", ").append(GL41.glGetString(GL41.GL_VENDOR)).append("\n\n");
+            s.append("OpenGL: ").append(OpenGLHelper.renderer).append(" version ").append(OpenGLHelper.version).append(", ").append(OpenGLHelper.vendor).append("\n\n");
         } catch (Throwable throwable) {
             s.append("[failed to get system properties (").append(throwable).append(")]\n\n");
         }
@@ -43,15 +42,14 @@ public class ExceptionPopupElement {
         s.append(TextFormatting.WHITE);
 
 
-        return new PopupBuilder(parent, 860 / scale).withLabel("gui.exception.label.exception_occurred")
-            .withMessageBox("gui.exception.list", 400 / scale, s.toString(), (860 / scale) / mc.font.getFont().charWidth('m'))
+        return new PopupBuilder(parent, mc.resolution.getScaledWidthScreenCoords() - 60).withLabel("gui.exception.label.exception_occurred")
+            .withMessageBox("gui.exception.list", mc.resolution.getScaledHeightScreenCoords() - 120, s.toString(), (mc.resolution.getScaledWidthScreenCoords() - 60) / mc.font.getFont().charWidth('m'))
             .withButtonGroup("gui.exception.choice", new String[]{"gui.exception.button.back", "gui.exception.button.copy_error"}, new int[]{0, 1})
             .withOnCloseListener(new PopupListener(mc, s.toString().replaceAll("§[0-9a-f|klmnor]", "")))
             .build();
     }
 
     public static PopupScreen createFatal(Throwable e, Minecraft mc) {
-        int scale = Math.max(mc.resolution.getScale(), 1);
         StringBuilder s = new StringBuilder("Minecraft ran into an unexpected problem that it cannot recover from!\n\n");
         s.append("The current game has quit, please restart the game.\n\n");
         s.append("If you wish to report this, please copy this entire text and post it on the support portal at")
@@ -65,7 +63,7 @@ public class ExceptionPopupElement {
             s.append("Java: ").append(System.getProperty("java.version")).append(", ").append(System.getProperty("java.vendor")).append("\n");
             s.append("VM: ").append(System.getProperty("java.vm.name")).append(" (").append(System.getProperty("java.vm.info")).append("), ").append(System.getProperty("java.vm.vendor")).append("\n");
             s.append("LWJGL: ").append(Sys.getVersion()).append("\n");
-            s.append("OpenGL: ").append(GL41.glGetString(GL41.GL_RENDERER)).append(" version ").append(GL41.glGetString(GL41.GL_VERSION)).append(", ").append(GL41.glGetString(GL41.GL_VENDOR)).append("\n\n");
+            s.append("OpenGL: ").append(OpenGLHelper.renderer).append(" version ").append(OpenGLHelper.version).append(", ").append(OpenGLHelper.vendor).append("\n\n");
         } catch (Throwable throwable) {
             s.append("[failed to get system properties (").append(throwable).append(")]\n\n");
         }
@@ -78,8 +76,8 @@ public class ExceptionPopupElement {
 
         ScreenBlank screen = new ScreenBlank();
         mc.displayScreen(screen);
-        return new PopupBuilder(screen, 860 / scale).withLabel("gui.exception.label.fatal_error")
-            .withMessageBox("gui.exception.list", 400 / scale, s.toString(), (860 / scale) / mc.font.getFont().charWidth('m'))
+        return new PopupBuilder(screen, mc.resolution.getScaledWidthScreenCoords() - 60).withLabel("gui.exception.label.fatal_error")
+            .withMessageBox("gui.exception.list", mc.resolution.getScaledHeightScreenCoords() - 120, s.toString(), (mc.resolution.getScaledWidthScreenCoords() - 60) / mc.font.getFont().charWidth('m'))
             .withButtonGroup("gui.exception.choice", new String[]{"gui.exception.button.copy_error", "gui.exception.button.copy_error_and_quit"}, new int[]{0, 2}, new boolean[]{false, true})
             .withBackgroundColor(0xff402020, 0xff501010)
             .withOnCloseListener(new PopupListener(mc, s.toString().replaceAll("§[0-9a-f|klmnor]", "")))
@@ -87,7 +85,6 @@ public class ExceptionPopupElement {
     }
 
     public static PopupScreen createStartupError(Throwable e, Minecraft mc) {
-        int scale = Math.max(mc.resolution.getScale(), 1);
         StringBuilder s = new StringBuilder("An error has prevented Minecraft from starting up correctly!\n\n");
         s.append("The game cannot continue, please restart the game.\n\n");
         s.append("If you wish to report this, please copy this entire text and post it on the support portal at")
@@ -101,8 +98,7 @@ public class ExceptionPopupElement {
             s.append("Java: ").append(System.getProperty("java.version")).append(", ").append(System.getProperty("java.vendor")).append("\n");
             s.append("VM: ").append(System.getProperty("java.vm.name")).append(" (").append(System.getProperty("java.vm.info")).append("), ").append(System.getProperty("java.vm.vendor")).append("\n");
             s.append("LWJGL: ").append(Sys.getVersion()).append("\n");
-            //s1 = GL41.glGetString(GL41.GL_VENDOR);
-            s.append("OpenGL: ").append(GL41.glGetString(GL41.GL_RENDERER)).append(" version ").append(GL41.glGetString(GL41.GL_VERSION)).append(", ").append(GL41.glGetString(GL41.GL_VENDOR)).append("\n\n");
+            s.append("OpenGL: ").append(OpenGLHelper.renderer).append(" version ").append(OpenGLHelper.version).append(", ").append(OpenGLHelper.vendor).append("\n\n");
         } catch (Throwable throwable) {
             s.append("[failed to get system properties (").append(throwable).append(")]\n\n");
         }
@@ -115,8 +111,8 @@ public class ExceptionPopupElement {
 
         ScreenBlank screen = new ScreenBlank();
         mc.displayScreen(screen);
-        return new PopupBuilder(screen, 860 / scale).withLabel("gui.exception.label.startup_error")
-            .withMessageBox("gui.exception.list", 400 / scale, s.toString(), (860 / scale) / mc.font.getFont().charWidth('m'))
+        return new PopupBuilder(screen, mc.resolution.getScaledWidthScreenCoords() - 60).withLabel("gui.exception.label.startup_error")
+            .withMessageBox("gui.exception.list", mc.resolution.getScaledHeightScreenCoords() - 120, s.toString(), (mc.resolution.getScaledWidthScreenCoords() - 60) / mc.font.getFont().charWidth('m'))
             .withButtonGroup("gui.exception.choice", new String[]{"gui.exception.button.copy_error", "gui.exception.button.copy_error_and_quit"}, new int[]{0, 2}, new boolean[]{false, true})
             .withBackgroundColor(0xff402020, 0xff501010)
             .withOnCloseListener(new PopupListener(mc, s.toString().replaceAll("§[0-9a-f|klmnor]", "")))
diff --git a/game/client/src/main/java/net/minecraft/client/gui/HeldItemTooltipElement.java b/game/client/src/main/java/net/minecraft/client/gui/HeldItemTooltipElement.java
index 9f445687c..2f19fb116 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/HeldItemTooltipElement.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/HeldItemTooltipElement.java
@@ -1,6 +1,7 @@
 package net.minecraft.client.gui;
 
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.option.Option;
 import net.minecraft.client.render.renderer.BlendFactor;
 import net.minecraft.client.render.renderer.GLRenderer;
@@ -8,12 +9,11 @@ import net.minecraft.client.render.renderer.State;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.client.util.helper.Colors;
 import net.minecraft.core.util.helper.Time;
+import org.jetbrains.annotations.NotNull;
 
 public class HeldItemTooltipElement extends Gui {
 
-	private final Minecraft mc;
-	
-	private int lastItemID;
+    private int lastItemID;
 	private int lastSelectedItem;
 	
 	private String string;
@@ -25,12 +25,10 @@ public class HeldItemTooltipElement extends Gui {
 	private final double displayTime = 2.5;
 	private final double fadeTime = 0.5;
 	
-	public HeldItemTooltipElement(Minecraft mc) {
-		this.mc = mc;
-	}
+	public HeldItemTooltipElement() {}
 	
 	public void updateAndRender(Minecraft mc, int width, int height, int screenPadding) {
-		if(mc.gameSettings.heldItemTooltips.value) {
+		if(GameSettings.HELD_ITEM_TOOLTIPS.value) {
 			ItemStack item = mc.thePlayer.getCurrentEquippedItem();
 			
 			int id = getItemID(item);
@@ -49,7 +47,7 @@ public class HeldItemTooltipElement extends Gui {
 		render(mc, width, height, screenPadding);
 	}
 	public void updateAndRender(Minecraft mc, int x, int y) {
-		if(mc.gameSettings.heldItemTooltips.value) {
+		if(GameSettings.HELD_ITEM_TOOLTIPS.value) {
 			ItemStack item = mc.thePlayer.getCurrentEquippedItem();
 
 			int id = getItemID(item);
@@ -78,8 +76,8 @@ public class HeldItemTooltipElement extends Gui {
 		this.color = Colors.allChatColors[item.getDisplayColor()].getARGB();
 	}
 	
-	public void setOptionNameAndValueString(Option<?> option) {
-		setString(option.getDisplayStringName() + ": " + this.mc.gameSettings.getDisplayString(option));
+	public void setOptionNameAndValueString(@NotNull Option<?> option) {
+		setString(option.getDisplayStringName() + ": " + option.getDisplayString());
 	}
 	
 	public void setString(String string) {
diff --git a/game/client/src/main/java/net/minecraft/client/gui/Screen.java b/game/client/src/main/java/net/minecraft/client/gui/Screen.java
index 0e9676970..1f9f69bf6 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/Screen.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/Screen.java
@@ -5,6 +5,7 @@ import java.util.List;
 
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.input.controller.ControllerInput;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.font.FontRenderer;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
@@ -131,7 +132,7 @@ public abstract class Screen extends Gui {
             }
         }
         while (Keyboard.next()) {
-            if (Keyboard.getEventKeyState() && this.mc.gameSettings.showFrameTimes.isTrue() && DebugRender.keyPressed(Keyboard.getEventKey())) {
+            if (Keyboard.getEventKeyState() && GameSettings.SHOW_FRAME_TIMES.isTrue() && DebugRender.keyPressed(Keyboard.getEventKey())) {
                 continue;
             }
             final int eventKey = Keyboard.getEventKey();
@@ -145,7 +146,7 @@ public abstract class Screen extends Gui {
                     this.mc.gameWindow.toggleFullscreen();
                     return;
                 }
-                if (!(this instanceof ScreenConsole) && eventKey == this.mc.gameSettings.keyShowConsole.getKeyCode() && this.mc.gameSettings.developerMode.isTrue() && !Keyboard.areRepeatEventsEnabled()) {
+                if (!(this instanceof ScreenConsole) && eventKey == GameSettings.KEY_SHOW_CONSOLE.getKeyCode() && GameSettings.DEVELOPER_MODE.isTrue() && !Keyboard.areRepeatEventsEnabled()) {
                     this.mc.displayScreen(new ScreenConsole(this));
                     return;
                 }
@@ -162,7 +163,7 @@ public abstract class Screen extends Gui {
 
     public void renderBackground() {
         if (this.mc.currentWorld != null) {
-            final int color = this.mc.gameSettings.guiBackgroundColor.value.getARGB();
+            final int color = GameSettings.GUI_BACKGROUND_COLOR.value.getARGB();
             this.drawGradientRect(0, 0, this.width, this.height, color, color);
         } else {
             this.renderTexturedBackground();
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenConsole.java b/game/client/src/main/java/net/minecraft/client/gui/ScreenConsole.java
index 92594d1fb..b8a039991 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenConsole.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/ScreenConsole.java
@@ -8,6 +8,7 @@ import net.minecraft.client.console.syntax.RendererFactory;
 import net.minecraft.client.gui.text.ITextField;
 import net.minecraft.client.gui.text.TextFieldEditor;
 import net.minecraft.client.console.shell.RuntimeExecutor;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.font.Fonts;
 import net.minecraft.client.render.window.CursorShape;
 import net.minecraft.core.net.command.TextFormatting;
@@ -463,7 +464,7 @@ public class ScreenConsole extends Screen {
 
     @Override
     public void keyPressed(char eventCharacter, int eventKey, int mx, int my) {
-        if (eventKey == this.mc.gameSettings.keyShowConsole.getKeyCode() || eventKey == Keyboard.KEY_ESCAPE) {
+        if (eventKey == GameSettings.KEY_SHOW_CONSOLE.getKeyCode() || eventKey == Keyboard.KEY_ESCAPE) {
             this.mc.displayScreen(this.parentScreen);
         } else {
             if (eventKey == Keyboard.KEY_RETURN) {
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenControllerSetup.java b/game/client/src/main/java/net/minecraft/client/gui/ScreenControllerSetup.java
index db1d1d5eb..a80248113 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenControllerSetup.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/ScreenControllerSetup.java
@@ -5,6 +5,7 @@ import net.minecraft.client.input.InputType;
 import net.minecraft.client.input.controller.Button;
 import net.minecraft.client.input.controller.ControllerInput;
 import net.minecraft.client.input.controller.ControllerType;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
 import net.minecraft.core.lang.I18n;
@@ -176,11 +177,11 @@ public class ScreenControllerSetup extends Screen {
 
     private void save() {
         if (this.mc.controllerInput != null) {
-            this.mc.gameSettings.selectedController.value = this.mc.controllerInput.getGUID();
+            GameSettings.SELECTED_CONTROLLER.value = this.mc.controllerInput.getGUID();
         } else {
-            this.mc.gameSettings.selectedController.value = "";
+            GameSettings.SELECTED_CONTROLLER.value = "";
         }
-        this.mc.gameSettings.saveOptions();
+        GameSettings.saveOptions();
     }
 
     private void drawButton(ControllerInput controller, Button button, int x, int y, boolean pressed) {
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenHudDesigner.java b/game/client/src/main/java/net/minecraft/client/gui/ScreenHudDesigner.java
index 37d35421e..b213c7a3a 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenHudDesigner.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/ScreenHudDesigner.java
@@ -7,6 +7,7 @@ import net.minecraft.client.gui.hud.component.HudComponentMovable;
 import net.minecraft.client.gui.hud.component.layout.LayoutAbsolute;
 import net.minecraft.client.gui.hud.component.layout.Layout;
 import net.minecraft.client.gui.hud.component.layout.LayoutSnap;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.Shaders;
 import net.minecraft.client.render.renderer.State;
@@ -36,8 +37,8 @@ public class ScreenHudDesigner
     @Override
     public void init() {
         super.init();
-        this.screenPadding = this.mc.gameSettings.screenPadding.value;
-        this.mc.gameSettings.screenPadding.set(0.0f);
+        this.screenPadding = GameSettings.SCREEN_PADDING.value;
+        GameSettings.SCREEN_PADDING.set(0.0f);
 
         add(new ButtonElement(0, this.width / 2 - 100, this.height - BOTTOM_SPACE + (BOTTOM_SPACE - 20) / 2, 178, 20, I18n.getInstance().translateKey("gui.hud_designer.button.done")));
         add(this.resetButton = new ButtonElement(1, this.width / 2 + 80, this.height - BOTTOM_SPACE + (BOTTOM_SPACE - 20) / 2, 20, 20, "")
@@ -47,7 +48,7 @@ public class ScreenHudDesigner
     @Override
     public void removed() {
         super.removed();
-        this.mc.gameSettings.screenPadding.set(this.screenPadding);
+        GameSettings.SCREEN_PADDING.set(this.screenPadding);
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenLabelEditor.java b/game/client/src/main/java/net/minecraft/client/gui/ScreenLabelEditor.java
index 86d3d761a..f0f276e61 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenLabelEditor.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/ScreenLabelEditor.java
@@ -4,6 +4,7 @@ import net.minecraft.client.gui.keyboard.ScreenKeyboard;
 import net.minecraft.client.gui.text.ITextField;
 import net.minecraft.client.gui.text.TextFieldEditor;
 import net.minecraft.client.input.InputType;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.lang.I18n;
@@ -42,7 +43,7 @@ public class ScreenLabelEditor extends Screen implements ITextField {
     @Override
     public void tick() {
         this.cursorCounter++;
-        if ((this.mc.gameSettings.forceOnscreenKeyboard.value || this.mc.inputType == InputType.CONTROLLER) && !(this.mc.currentScreen instanceof ScreenKeyboard)) {
+        if ((GameSettings.FORCE_ONSCREEN_KEYBOARD.value || this.mc.inputType == InputType.CONTROLLER) && !(this.mc.currentScreen instanceof ScreenKeyboard)) {
             buttonClicked(this.buttons.get(0)); // Close out of gui when exiting keyboard screen
         }
     }
@@ -92,14 +93,11 @@ public class ScreenLabelEditor extends Screen implements ITextField {
         Keyboard.enableRepeatEvents(true);
         this.buttons.add(new ButtonElement(0, this.width / 2 - 100, this.height / 4 + 120, I18n.getInstance().translateKey("gui.edit_label.button.done")));
 
-        if (this.mc.gameSettings.forceOnscreenKeyboard.value || this.mc.inputType == InputType.CONTROLLER) {
+        if (GameSettings.FORCE_ONSCREEN_KEYBOARD.value || this.mc.inputType == InputType.CONTROLLER) {
             this.mc.displayScreen(new ScreenKeyboard(this, this.editor,
-                (s) -> {
-                },
-                (c, k, s) -> {
-                },
-                s -> {
-                }));
+                (s) -> {},
+                (c, k, s) -> {},
+                s -> {}));
         }
     }
 
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 d44c7b9e0..106f1b9ce 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,25 +1,15 @@
 package net.minecraft.client.gui;
 
-import java.awt.image.BufferedImage;
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Random;
-
-import javax.crypto.Cipher;
-import javax.imageio.ImageIO;
-
 import com.mojang.logging.LogUtils;
+import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.error.ScreenMissingJCE;
 import net.minecraft.client.gui.hud.HudIngame;
 import net.minecraft.client.gui.hud.HudIngameDoom;
+import net.minecraft.client.gui.options.ScreenOptions;
+import net.minecraft.client.gui.options.data.OptionsPages;
 import net.minecraft.client.gui.server.ScreenSelectServer;
 import net.minecraft.client.holiday.Holidays;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.Lighting;
 import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.block.model.BlockModelDispatcher;
@@ -32,21 +22,30 @@ import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.client.util.helper.UrlHelper;
 import net.minecraft.core.Version;
-import org.jetbrains.annotations.NotNull;
-import org.joml.Math;
-import org.lwjgl.input.Keyboard;
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.options.ScreenOptions;
-import net.minecraft.client.gui.options.data.OptionsPages;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.sound.SoundCategory;
 import net.minecraft.core.util.helper.MathHelper;
+import org.jetbrains.annotations.NotNull;
+import org.joml.Math;
+import org.lwjgl.input.Keyboard;
 import org.lwjgl.opengl.GL41;
 import org.slf4j.Logger;
 
+import javax.crypto.Cipher;
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Random;
+
 public class ScreenMainMenu extends Screen {
     private static final Logger LOGGER = LogUtils.getLogger();
 
@@ -194,7 +193,7 @@ public class ScreenMainMenu extends Screen {
                 } catch (final Exception ignored) {
                     hasJCE = false;
                 }
-                if (!(hasJCE) && this.mc.gameSettings.doJCECheck.value) {
+                if (!(hasJCE) && GameSettings.DO_JCE_CHECK.value) {
                     this.mc.displayScreen(new ScreenMissingJCE(this, new ScreenSelectServer(this)));
                 } else {
                     this.mc.displayScreen(new ScreenSelectServer(this));
@@ -236,7 +235,7 @@ public class ScreenMainMenu extends Screen {
 
     @Override
     public void renderTexturedBackground() {
-        if (this.mc.mainMenuBackground.isEnabled() && !this.mc.gameSettings.alphaMenu.value) {
+        if (this.mc.mainMenuBackground.isEnabled() && !GameSettings.ALPHA_MENU.value) {
             this.mc.mainMenuBackground.draw();
         } else {
             super.renderTexturedBackground();
@@ -257,7 +256,7 @@ public class ScreenMainMenu extends Screen {
             }
         }
 
-        if (this.mc.gameSettings.playTitleScreenMusic.value) {
+        if (GameSettings.PLAY_TITLE_SCREEN_MUSIC.value) {
             this.mc.sndManager.playTitleScreenMusic();
         }
     }
@@ -273,8 +272,8 @@ public class ScreenMainMenu extends Screen {
         if (mx >= logoX + p && mx <= logoX + 270 - p && my >= logoHeight + p && my <= logoHeight + 48 - p) {
             if (this.logoClickCounter >= 0) {
                 this.indexToDraw = rand.nextInt(BLOCKS_TO_DRAW.length);
-                this.mc.gameSettings.alphaMenu.toggle();
-                if (this.mc.gameSettings.alphaMenu.value) this.logoBlocks = null;
+                GameSettings.ALPHA_MENU.toggle();
+                if (GameSettings.ALPHA_MENU.value) this.logoBlocks = null;
                 this.logoClickCounter = 0;
             } else {
                 this.logoClickCounter++;
@@ -294,7 +293,7 @@ public class ScreenMainMenu extends Screen {
         int c = 274;
         int k = this.width / 2 - c / 2;
         byte byte0 = 30;
-        if (!this.mc.gameSettings.alphaMenu.value) {
+        if (!GameSettings.ALPHA_MENU.value) {
             this.mc.textureManager.loadTexture("/assets/minecraft/textures/gui/title/mclogo.png").bind();
             GLRenderer.setColor4f(1f, 1f, 1f, 1f);
             drawTexturedModalRect(k, byte0, 0, 0, 274, 50, 1d / 274, 1d / 50);
@@ -320,7 +319,7 @@ public class ScreenMainMenu extends Screen {
         GLRenderer.modelM4f().scale(scalar, scalar, scalar);
         drawStringCenteredShadow(this.fontRenderer, this.splashText, 0, -8, 0xffff00);
         GLRenderer.popFrame();
-        int versionTextColor = this.mc.gameSettings.alphaMenu.value || !this.mc.mainMenuBackground.isEnabled() ? 0x505050 : 0xFFFFFF;
+        int versionTextColor = GameSettings.ALPHA_MENU.value || !this.mc.mainMenuBackground.isEnabled() ? 0x505050 : 0xFFFFFF;
         if (this.showBuildTime) {
             drawStringShadow(this.fontRenderer, this.buildTimeString, 2, 2, versionTextColor);
         } else {
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 3f70c7f8b..7018b3aa5 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
@@ -208,7 +208,7 @@ public class ScreenPhotoMode extends Screen {
             if (this.desiredSeason == -1) {
                 this.desiredDay = this.originalTOD / Global.DAY_LENGTH_TICKS;
             } else {
-                this.desiredDay = (long) Global.DAY_LENGTH_TICKS * 7 * this.desiredSeason + Global.DAY_LENGTH_TICKS * 3L;
+                this.desiredDay = (long) Global.DAY_LENGTH_TICKS * 14 * this.desiredSeason + Global.DAY_LENGTH_TICKS * 3L;
             }
 
             this.mc.currentWorld.setWorldTimeUpdateTicks(this.desiredDay + this.desiredTOD);
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenSignEditor.java b/game/client/src/main/java/net/minecraft/client/gui/ScreenSignEditor.java
index 7fb04b990..ace3a5240 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenSignEditor.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/ScreenSignEditor.java
@@ -4,6 +4,7 @@ import net.minecraft.client.gui.keyboard.ScreenKeyboard;
 import net.minecraft.client.gui.modelviewer.elements.ListenerButtonElement;
 import net.minecraft.client.input.InputType;
 import net.minecraft.client.input.controller.ControllerInput;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.TileEntityRenderDispatcher;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
@@ -69,7 +70,7 @@ public class ScreenSignEditor extends Screen {
                 this.inKeyboard = true;
             })).mute().hide();
 
-        this.inKeyboard = (this.mc.gameSettings.forceOnscreenKeyboard.value || this.mc.inputType == InputType.CONTROLLER) && !(this.mc.currentScreen instanceof ScreenKeyboard);
+        this.inKeyboard = (GameSettings.FORCE_ONSCREEN_KEYBOARD.value || this.mc.inputType == InputType.CONTROLLER) && !(this.mc.currentScreen instanceof ScreenKeyboard);
     }
 
     @Override
@@ -135,7 +136,7 @@ public class ScreenSignEditor extends Screen {
     @Override
     public void render(int mx, int my, float partialTick) {
         GLRenderer.setColor4f(1f, 1f, 1f, 1f);
-        if (this.inKeyboard && (this.mc.gameSettings.forceOnscreenKeyboard.value || this.mc.inputType == InputType.CONTROLLER) && !(this.mc.currentScreen instanceof ScreenKeyboard)) {
+        if (this.inKeyboard && (GameSettings.FORCE_ONSCREEN_KEYBOARD.value || this.mc.inputType == InputType.CONTROLLER) && !(this.mc.currentScreen instanceof ScreenKeyboard)) {
             if (this.editLine < this.entitySign.signText.length) {
                 ScreenKeyboard keyboard = new ScreenKeyboard(this, null,
                     (s) -> {
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenSoundTest.java b/game/client/src/main/java/net/minecraft/client/gui/ScreenSoundTest.java
index f8719f5ed..b07dac7ac 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenSoundTest.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/ScreenSoundTest.java
@@ -107,7 +107,7 @@ public class ScreenSoundTest extends Screen {
         add(new ListenerButtonElement(32, 40 + BUTTON_SPACING * 3, this.bottom - (BUTTON_SPACING + 20), 40, 20, I18n.getInstance().translateKey("gui.sound_test.button.reload")))
             .setActionListener(() -> {
                 this.mc.sndManager = new SoundEngine();
-                this.mc.sndManager.init(this.mc.gameSettings);
+                this.mc.sndManager.init();
                 initRepos();
             });
 
diff --git a/game/client/src/main/java/net/minecraft/client/gui/TextFieldElement.java b/game/client/src/main/java/net/minecraft/client/gui/TextFieldElement.java
index 9bceeabe6..f30db0ad2 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/TextFieldElement.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/TextFieldElement.java
@@ -4,6 +4,7 @@ import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.keyboard.ScreenKeyboard;
 import net.minecraft.client.gui.text.TextFieldEditor;
 import net.minecraft.client.input.InputType;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.font.FontRenderer;
 import net.minecraft.client.render.window.CursorShape;
 import net.minecraft.core.util.helper.MathHelper;
@@ -29,12 +30,12 @@ public class TextFieldElement extends Gui implements ITextField
 	private ITextChangeListener textChangeListener;
     private String placeholder;
     public boolean drawBackground = true;
-    private TextFieldEditor editor;
+    private final TextFieldEditor editor;
 
     public TextFieldElement(@Nullable Screen parent, FontRenderer fontRenderer, int xPosition, int yPosition, int width, int height, String defaultText, String placeholder)
     {
-        isFocused = false;
-        isEnabled = true;
+        this.isFocused = false;
+        this.isEnabled = true;
         this.parent = parent;
         this.fontRenderer = fontRenderer;
         this.xPosition = xPosition;
@@ -44,25 +45,25 @@ public class TextFieldElement extends Gui implements ITextField
         this.editor = new TextFieldEditor(this);
         this.placeholder = placeholder;
         setText(defaultText);
-        editor.setCursor(10000);
+        this.editor.setCursor(10000);
     }
 
     @Override
     public void setText(String text)
     {
-        if (text == null) editor.setCursor(0);
-        else if (text.length() < editor.getCursor())
+        if (text == null) this.editor.setCursor(0);
+        else if (text.length() < this.editor.getCursor())
         {
-            editor.setCursor(text.length());
+            this.editor.setCursor(text.length());
         }
         this.text = text;
-        if(textChangeListener != null) textChangeListener.textChanged(this);
+        if(this.textChangeListener != null) this.textChangeListener.textChanged(this);
     }
 
     @Override
     public String getText()
     {
-        return text;
+        return this.text;
     }
 
     public void setPlaceholder(String placeholder) {
@@ -71,30 +72,30 @@ public class TextFieldElement extends Gui implements ITextField
 
     public void updateCursorCounter()
     {
-        cursorCounter++;
+        this.cursorCounter++;
     }
 
     public void textboxKeyTyped(char c, int key)
     {
-        if(!isEnabled || !isFocused)
+        if(!this.isEnabled || !this.isFocused)
         {
             return;
         }
         if(key == Keyboard.KEY_TAB) {
-            if (parent != null) {
-                parent.selectNextField();
+            if (this.parent != null) {
+                this.parent.selectNextField();
             }
         }
-        if(editor.handleInput(key, c)) {
-        	if(textChangeListener != null) textChangeListener.textChanged(this);
+        if(this.editor.handleInput(key, c)) {
+        	if(this.textChangeListener != null) this.textChangeListener.textChanged(this);
         }
     }
 
     public void mouseClicked(int x, int y, int mouseButton)
     {
         boolean hovered = isHovered(x, y);
-        if (parent != null && ((Minecraft.getMinecraft().inputType == InputType.CONTROLLER || Minecraft.getMinecraft().gameSettings.forceOnscreenKeyboard.value) && hovered && mouseButton == 0)) {
-            this.parent.mc.displayScreen(new ScreenKeyboard(parent, editor, s -> {}, (c, k, workingString) -> {}, s -> {}));
+        if (this.parent != null && ((Minecraft.getMinecraft().inputType == InputType.CONTROLLER || GameSettings.FORCE_ONSCREEN_KEYBOARD.value) && hovered && mouseButton == 0)) {
+            this.parent.mc.displayScreen(new ScreenKeyboard(this.parent, this.editor, s -> {}, (c, k, workingString) -> {}, s -> {}));
         } else {
             setFocused(hovered);
             if(hovered && mouseButton == 1) {
@@ -104,21 +105,21 @@ public class TextFieldElement extends Gui implements ITextField
     }
 
     public boolean isHovered(int x, int y) {
-        return isEnabled && x >= xPosition && x < xPosition + width && y >= yPosition && y < yPosition + height;
+        return this.isEnabled && x >= this.xPosition && x < this.xPosition + this.width && y >= this.yPosition && y < this.yPosition + this.height;
     }
 
     public void setFocused(boolean flag)
     {
-        if(flag && !isFocused)
+        if(flag && !this.isFocused)
         {
-            cursorCounter = 0;
-            editor.setCursor(10000);
+            this.cursorCounter = 0;
+            this.editor.setCursor(10000);
         }
-        isFocused = flag;
+        this.isFocused = flag;
     }
 
     public void updateCursor(Minecraft mc, int mx, int my) {
-        boolean hovered = isEnabled && mx >= xPosition && mx < xPosition + width && my >= yPosition && my < yPosition + height;
+        boolean hovered = this.isEnabled && mx >= this.xPosition && mx < this.xPosition + this.width && my >= this.yPosition && my < this.yPosition + this.height;
         if (hovered) {
             mc.currentScreen.setDesiredCursor(CursorShape.I_BEAM);
         }
@@ -126,58 +127,58 @@ public class TextFieldElement extends Gui implements ITextField
 
     public void drawTextBox()
     {
-        if (drawBackground)
+        if (this.drawBackground)
         {
-            drawRect(xPosition - 1, yPosition - 1, xPosition + width + 1, yPosition + height + 1, 0xffa0a0a0);
-            drawRect(xPosition, yPosition, xPosition + width, yPosition + height, 0xff000000);
+            drawRect(this.xPosition - 1, this.yPosition - 1, this.xPosition + this.width + 1, this.yPosition + this.height + 1, 0xffa0a0a0);
+            drawRect(this.xPosition, this.yPosition, this.xPosition + this.width, this.yPosition + this.height, 0xff000000);
         }
-        if (text.isEmpty() && !isFocused)
+        if (this.text.isEmpty() && !this.isFocused)
         {
-            drawStringShadow(fontRenderer, placeholder, xPosition + 4, yPosition + (height - 8) / 2, 0x5f5f5f);
+            drawStringShadow(this.fontRenderer, this.placeholder, this.xPosition + 4, this.yPosition + (this.height - 8) / 2, 0x5f5f5f);
         }
 
-        if(isEnabled)
+        if(this.isEnabled)
         {
-            boolean drawCursor = isFocused && (cursorCounter / 6) % 2 == 0;
-            int cursor = editor.getCursor();
-            int maxDisplayableChars = this.width / fontRenderer.getFont().charWidth('_');
+            boolean drawCursor = this.isFocused && (this.cursorCounter / 6) % 2 == 0;
+            int cursor = this.editor.getCursor();
+            int maxDisplayableChars = this.width / this.fontRenderer.getFont().charWidth('_');
 
-            if(text.length() <= maxDisplayableChars-1){
-                drawStringShadow(fontRenderer, text, xPosition + 4, yPosition + (height - 8) / 2, 0xE0E0E0);
+            if(this.text.length() <= maxDisplayableChars-1){
+                drawStringShadow(this.fontRenderer, this.text, this.xPosition + 4, this.yPosition + (this.height - 8) / 2, 0xE0E0E0);
             } else {
                 //only draw the part of the string that's maxDisplayableChars chars around the cursor
                 int begin = Math.max(0,cursor - maxDisplayableChars);
-                int end = Math.max(maxDisplayableChars,Math.min(text.length(),cursor));
-                drawStringShadow(fontRenderer, text.substring(begin, end), xPosition + 4, yPosition + (height - 8) / 2, 0xE0E0E0);
+                int end = Math.max(maxDisplayableChars,Math.min(this.text.length(),cursor));
+                drawStringShadow(this.fontRenderer, this.text.substring(begin, end), this.xPosition + 4, this.yPosition + (this.height - 8) / 2, 0xE0E0E0);
             }
             if (drawCursor)
             {
-                int width = MathHelper.ceil(fontRenderer.stringWidthDouble(text));
-                if (cursor < text.length())
+                int width = MathHelper.ceil(this.fontRenderer.stringWidthDouble(this.text));
+                if (cursor < this.text.length())
                 {
-                    width = MathHelper.ceil(fontRenderer.stringWidthDouble(text.substring(0, cursor)));
+                    width = MathHelper.ceil(this.fontRenderer.stringWidthDouble(this.text.substring(0, cursor)));
                 }
                 if(width >= this.width-4){
                     // width of the text box - the width of the last character
-                    width = (this.width-4) - MathHelper.ceil(fontRenderer.stringWidthDouble(text.substring(text.length()-2,text.length()-1)));
+                    width = (this.width-4) - MathHelper.ceil(this.fontRenderer.stringWidthDouble(this.text.substring(this.text.length()-2, this.text.length()-1)));
                 }
-                drawStringShadow(fontRenderer, "_", xPosition + 4 + width, yPosition + (height - 8) / 2 + 1, 0xE0E0E0);
+                drawStringShadow(this.fontRenderer, "_", this.xPosition + 4 + width, this.yPosition + (this.height - 8) / 2 + 1, 0xE0E0E0);
             }
         }
         else
         {
-            drawStringShadow(fontRenderer, text, xPosition + 4, yPosition + (height - 8) / 2, 0x707070);
+            drawStringShadow(this.fontRenderer, this.text, this.xPosition + 4, this.yPosition + (this.height - 8) / 2, 0x707070);
         }
     }
 
     public void setMaxStringLength(int i)
     {
-        maxStringLength = i;
+        this.maxStringLength = i;
     }
 
 	@Override
     public int maxLength() {
-		return maxStringLength == 0 ? 1000 : maxStringLength;
+		return this.maxStringLength == 0 ? 1000 : this.maxStringLength;
 	}
     
     public void setTextChangeListener(ITextChangeListener textChangeListener) {
diff --git a/game/client/src/main/java/net/minecraft/client/gui/TooltipElement.java b/game/client/src/main/java/net/minecraft/client/gui/TooltipElement.java
index 9345d8e73..5940c6dc8 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/TooltipElement.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/TooltipElement.java
@@ -7,6 +7,7 @@ import com.google.gson.JsonParser;
 import com.google.gson.stream.JsonReader;
 import com.mojang.logging.LogUtils;
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.font.FontRenderer;
 import net.minecraft.client.render.renderer.BlendFactor;
 import net.minecraft.client.render.renderer.CompareFunc;
@@ -123,7 +124,7 @@ public class TooltipElement extends Gui {
     }
 
     private int[] drawBackground(final int minX, final int minY, final int maxX, final int maxY) {
-        final Style style = styleMap.getOrDefault(this.mc.gameSettings.tooltipStyle.value, defaultStyle);
+        final Style style = styleMap.getOrDefault(GameSettings.TOOLTIP_STYLE.value, defaultStyle);
         if (style != null) {
             GLRenderer.pushFrame();
             GLRenderer.setDepthFunc(CompareFunc.ALWAYS);
@@ -155,7 +156,7 @@ public class TooltipElement extends Gui {
         boolean discovered = true;
         boolean ctrlPressed = false;
         boolean shiftPressed = false;
-        boolean debug = this.mc.gameSettings.showItemDebugInfo.value;
+        boolean debug = GameSettings.SHOW_ITEM_DEBUG_INFO.value;
 
         if (slot != null) {
             discovered = slot.getIsDiscovered(this.mc.thePlayer);
@@ -165,7 +166,7 @@ public class TooltipElement extends Gui {
                 shiftPressed = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT);
 
                 showDescription = false;
-                if (this.mc.gameSettings.swapCraftingButtons.value) {
+                if (GameSettings.SWAP_CRAFTING_BUTTONS.value) {
                     boolean temp = shiftPressed;
                     shiftPressed = ctrlPressed;
                     ctrlPressed = temp;
@@ -214,7 +215,7 @@ public class TooltipElement extends Gui {
                 }
             }
 
-            if (itemStack.isItemStackDamageable() && !showDescription && this.mc.gameSettings.showItemDebugInfo.value) {
+            if (itemStack.isItemStackDamageable() && !showDescription && GameSettings.SHOW_ITEM_DEBUG_INFO.value) {
                 int durability = itemStack.getMaxDamage();
                 int remainingUses = durability - itemStack.getMetadata();
 
@@ -223,8 +224,8 @@ public class TooltipElement extends Gui {
 
             if (showDescription) {
                 text.append('\n').append(formatDescription(itemStack.getItemDescription(), 16));
-            } else if (!(slot instanceof SlotResult) && this.mc.gameSettings.itemDescriptions.value != DescriptionPromptEnum.NEVER_PROMPT) {
-                text.append('\n').append(formatDescription(trans.translateKeyAndFormat("gui.tooltip.prompt.description", this.mc.gameSettings.keyDescription.getKeyName()), 16));
+            } else if (!(slot instanceof SlotResult) && GameSettings.ITEM_DESCRIPTIONS.value != DescriptionPromptEnum.NEVER_PROMPT) {
+                text.append('\n').append(formatDescription(trans.translateKeyAndFormat("gui.tooltip.prompt.description", GameSettings.KEY_DESCRIPTION.getKeyName()), 16));
             }
 
             if (slot instanceof SlotResult) {
@@ -361,8 +362,8 @@ public class TooltipElement extends Gui {
             styleMap.put("default", defaultStyle);
             stylesIdList.add("default");
         }
-        if (Minecraft.getMinecraft().gameSettings.tooltipStyle.getValueIndex() == -1) {
-            Minecraft.getMinecraft().gameSettings.tooltipStyle.set("default");
+        if (GameSettings.TOOLTIP_STYLE.getValueIndex() == -1) {
+            GameSettings.TOOLTIP_STYLE.set("default");
         }
     }
 
diff --git a/game/client/src/main/java/net/minecraft/client/gui/chat/ScreenChat.java b/game/client/src/main/java/net/minecraft/client/gui/chat/ScreenChat.java
index 2b4783051..708b0f6d4 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/chat/ScreenChat.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/chat/ScreenChat.java
@@ -6,6 +6,7 @@ import net.minecraft.client.gui.hud.component.ComponentAnchor;
 import net.minecraft.client.gui.keyboard.ScreenKeyboard;
 import net.minecraft.client.gui.text.TextFieldEditor;
 import net.minecraft.client.input.InputType;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.net.ChatEmotes;
 import org.lwjgl.input.Keyboard;
@@ -30,10 +31,10 @@ public class ScreenChat extends Screen implements ITextField {
 	}
 
 	public ScreenChat(String initialMessage) {
-		message = initialMessage;
-		updateCounter = 0;
-		editor = new TextFieldEditor(this);
-		editor.setCursor(10000);
+        this.message = initialMessage;
+        this.updateCounter = 0;
+        this.editor = new TextFieldEditor(this);
+        this.editor.setCursor(10000);
 	}
 
 	@Override
@@ -41,13 +42,13 @@ public class ScreenChat extends Screen implements ITextField {
 		Keyboard.enableRepeatEvents(true);
 		try {
 			int emotePickerYCells = (int)MathHelper.clamp(Math.ceil(ChatEmotes.getEmotes().size() / 5.0), 0, 4);
-			emotePicker = new GuiElementChatEmotePicker(mc, this, 5, emotePickerYCells);
-			showEmotePicker = false;
-			suggestionsElement = new GuiElementChatSuggestions(
-				mc,
-				editor,
+            this.emotePicker = new GuiElementChatEmotePicker(this.mc, this, 5, emotePickerYCells);
+            this.showEmotePicker = false;
+            this.suggestionsElement = new GuiElementChatSuggestions(
+                this.mc,
+                this.editor,
 				this,
-				(parent, child, minecraft, followParameters) -> 16 + (followParameters ? suggestionsElement.getDefaultParameterPosition() - 1 : 0),
+				(parent, child, minecraft, followParameters) -> 16 + (followParameters ? this.suggestionsElement.getDefaultParameterPosition() - 1 : 0),
 				(parent, child, minecraft, followParameters) -> minecraft.resolution.getScaledHeightScreenCoords() - 14,
 				ComponentAnchor.BOTTOM_LEFT
 			);
@@ -58,17 +59,17 @@ public class ScreenChat extends Screen implements ITextField {
 				this.suggestionsElement.updateSuggestions();
 			}
 
-			if (mc.gameSettings.forceOnscreenKeyboard.value || mc.inputType == InputType.CONTROLLER) {
-				suggestionsElement.hidden = true;
-				mc.displayScreen(new ScreenKeyboard(this, editor,
+			if (GameSettings.FORCE_ONSCREEN_KEYBOARD.value || this.mc.inputType == InputType.CONTROLLER) {
+                this.suggestionsElement.hidden = true;
+                this.mc.displayScreen(new ScreenKeyboard(this, this.editor,
 					(workingString) -> sendMessage(),
 					(c, k, workingString) -> {
-						suggestionsElement.hidden = !getText().startsWith("/");
-						suggestionsElement.keyTyped(c, k);
+                        this.suggestionsElement.hidden = !getText().startsWith("/");
+                        this.suggestionsElement.keyTyped(c, k);
 					},
 					s -> {
-						suggestionsElement.hidden = !getText().startsWith("/");
-						suggestionsElement.updateSuggestions();
+                        this.suggestionsElement.hidden = !getText().startsWith("/");
+                        this.suggestionsElement.updateSuggestions();
 					}));
 			}
 		} catch (Exception e) {
@@ -79,25 +80,25 @@ public class ScreenChat extends Screen implements ITextField {
 	@Override
 	public void removed() {
 		Keyboard.enableRepeatEvents(false);
-		mc.hudIngame.chatScroll = 0;
+        this.mc.hudIngame.chatScroll = 0;
 	}
 
 	@Override
 	public void tick() {
-		if ((mc.gameSettings.forceOnscreenKeyboard.value || mc.inputType == InputType.CONTROLLER) && !(mc.currentScreen instanceof ScreenKeyboard)) {
-			mc.displayScreen(null); // Close out of gui when exiting keyboard screen
+		if ((GameSettings.FORCE_ONSCREEN_KEYBOARD.value || this.mc.inputType == InputType.CONTROLLER) && !(this.mc.currentScreen instanceof ScreenKeyboard)) {
+            this.mc.displayScreen(null); // Close out of gui when exiting keyboard screen
 			return;
 		}
-		updateCounter++;
+        this.updateCounter++;
 
 		try {
 			int dWheel = Mouse.getDWheel();
 			if (dWheel != 0)
 			{
-				if (showEmotePicker) {
-					emotePicker.scrollOffset((int)(-dWheel / 0.1f));
+				if (this.showEmotePicker) {
+                    this.emotePicker.scrollOffset((int)(-dWheel / 0.1f));
 				} else {
-					mc.hudIngame.chatScroll += dWheel;
+                    this.mc.hudIngame.chatScroll += dWheel;
 				}
 			}
 
@@ -122,18 +123,18 @@ public class ScreenChat extends Screen implements ITextField {
 						handled = true;
 					}
 				}
-				if (!handled && !mc.thePlayer.messageHistory.isEmpty()) {
-					if (currentIndex == 0)
+				if (!handled && !this.mc.thePlayer.messageHistory.isEmpty()) {
+					if (this.currentIndex == 0)
 					{
-						originalMessage = getText();
+                        this.originalMessage = getText();
 					}
-					if (currentIndex < mc.thePlayer.messageHistory.size())
+					if (this.currentIndex < this.mc.thePlayer.messageHistory.size())
 					{
-						currentIndex++;
-						setText(getMessage(currentIndex));
+                        this.currentIndex++;
+						setText(getMessage(this.currentIndex));
 						this.editor.setCursor(10000);
 					}
-					editor.setCursor(10000);
+                    this.editor.setCursor(10000);
 					if (this.suggestionsElement != null) {
 						this.suggestionsElement.updateSuggestions();
 					}
@@ -148,20 +149,20 @@ public class ScreenChat extends Screen implements ITextField {
 						handled = true;
 					}
 				}
-				if (!handled && currentIndex > 0) {
-					if (currentIndex-1 == 0)
+				if (!handled && this.currentIndex > 0) {
+					if (this.currentIndex -1 == 0)
 					{
-						currentIndex--;
-						setText(originalMessage);
+                        this.currentIndex--;
+						setText(this.originalMessage);
 						this.editor.setCursor(10000);
 					}
 					else
 					{
-						currentIndex--;
-						setText(getMessage(currentIndex));
+                        this.currentIndex--;
+						setText(getMessage(this.currentIndex));
 						this.editor.setCursor(10000);
 					}
-					editor.setCursor(10000);
+                    this.editor.setCursor(10000);
 					if (this.suggestionsElement != null) {
 						this.suggestionsElement.updateSuggestions();
 					}
@@ -169,20 +170,20 @@ public class ScreenChat extends Screen implements ITextField {
 				}
 			}
 			if (eventKey == Keyboard.KEY_ESCAPE && !(this instanceof ScreenSleepMP)) {
-				mc.displayScreen(null);
+                this.mc.displayScreen(null);
 				handled = true;
 			}
 			if (eventKey == Keyboard.KEY_RETURN || eventKey == Keyboard.KEY_NUMPADENTER) {
-				String s = message.trim();
-				if (s.length() > 0) {
-					String s1 = message.trim();
-					mc.thePlayer.sendChatMessage(s1);
+				String s = this.message.trim();
+				if (!s.isEmpty()) {
+					String s1 = this.message.trim();
+                    this.mc.thePlayer.sendChatMessage(s1);
 				}
-				mc.displayScreen(null);
+                this.mc.displayScreen(null);
 				handled = true;
 			}
 			if (!handled) {
-				editor.handleInput(eventKey, eventCharacter);
+                this.editor.handleInput(eventKey, eventCharacter);
 			}
 			if (this.suggestionsElement != null) {
 				this.suggestionsElement.keyTyped(eventCharacter, eventKey);
@@ -193,10 +194,10 @@ public class ScreenChat extends Screen implements ITextField {
 	}
 
 	public void sendMessage() {
-		String s = message.trim();
-		if (s.length() > 0) {
-			String s1 = message.trim();
-			mc.thePlayer.sendChatMessage(s1);
+		String s = this.message.trim();
+		if (!s.isEmpty()) {
+			String s1 = this.message.trim();
+            this.mc.thePlayer.sendChatMessage(s1);
 		}
 	}
 
@@ -206,32 +207,32 @@ public class ScreenChat extends Screen implements ITextField {
 			// Draw emote picker button
 			int emotePickerButtonColor = 0x80000000;
 			int emotePickerTextColor = 0xE0E0E0;
-			if (mx >= 2 && mx < 14 && my >= height - 14 && my < height - 2)
+			if (mx >= 2 && mx < 14 && my >= this.height - 14 && my < this.height - 2)
 			{
 				emotePickerButtonColor = 0x80ffffff;
 				emotePickerTextColor = 0xffffffa0;
 			}
-			drawRect(2, height - 14, 14, height - 2, emotePickerButtonColor);
-			drawStringCenteredShadow(fontRenderer, Character.toString('\u263a'), 2 + 6, height - 12, emotePickerTextColor);
+			drawRect(2, this.height - 14, 14, this.height - 2, emotePickerButtonColor);
+			drawStringCenteredShadow(this.fontRenderer, Character.toString('\u263a'), 2 + 6, this.height - 12, emotePickerTextColor);
 
-			drawRect(16, height - 14, width - 2, height - 2, 0x80000000);
+			drawRect(16, this.height - 14, this.width - 2, this.height - 2, 0x80000000);
 
-			drawStringShadow(fontRenderer, this.suggestionsElement.getSuggestionPreview(), 16 + suggestionsElement.getDefaultParameterPosition(), mc.resolution.getScaledHeightScreenCoords() - 12, 0xFFFFFF);
-			boolean drawCursor = (updateCounter / 6) % 2 == 0;
-			int cursor = editor.getCursor();
-			drawStringShadow(fontRenderer, this.suggestionsElement.colorCodeText(message, true), 18, height - 12, 0xE0E0E0);
+			drawStringShadow(this.fontRenderer, this.suggestionsElement.getSuggestionPreview(), 16 + this.suggestionsElement.getDefaultParameterPosition(), this.mc.resolution.getScaledHeightScreenCoords() - 12, 0xFFFFFF);
+			boolean drawCursor = (this.updateCounter / 6) % 2 == 0;
+			int cursor = this.editor.getCursor();
+			drawStringShadow(this.fontRenderer, this.suggestionsElement.colorCodeText(this.message, true), 18, this.height - 12, 0xE0E0E0);
 			if (drawCursor)
 			{
-				int width = MathHelper.ceil(fontRenderer.stringWidthDouble(message));
-				if (cursor < message.length())
+				int width = MathHelper.ceil(this.fontRenderer.stringWidthDouble(this.message));
+				if (cursor < this.message.length())
 				{
-					width = MathHelper.ceil(fontRenderer.stringWidthDouble(message.substring(0, cursor)));
+					width = MathHelper.ceil(this.fontRenderer.stringWidthDouble(this.message.substring(0, cursor)));
 				}
-				drawStringShadow(fontRenderer, "_", 18 + width, height - 12, 0xE0E0E0);
+				drawStringShadow(this.fontRenderer, "_", 18 + width, this.height - 12, 0xE0E0E0);
 			}
 
-			if (showEmotePicker) {
-				emotePicker.draw(2, height - 16 - emotePicker.getHeight(), mx, my);
+			if (this.showEmotePicker) {
+                this.emotePicker.draw(2, this.height - 16 - this.emotePicker.getHeight(), mx, my);
 			}
 
 			super.render(mx, my, partialTick);
@@ -249,15 +250,16 @@ public class ScreenChat extends Screen implements ITextField {
 		try {
 			boolean handled = false;
 			if (buttonNum == 0) {
-				if (mx >= 2 && mx < 14 && my >= height - 14 && my < height - 2) {
-					showEmotePicker = !showEmotePicker;
+				if (mx >= 2 && mx < 14 && my >= this.height - 14 && my < this.height - 2) {
+                    this.showEmotePicker = !this.showEmotePicker;
 					handled = true;
 				}
-				if (!handled && showEmotePicker) {
-					Character c = emotePicker.click(mx - 2, my - (height - 16 - emotePicker.getHeight()));
+				if (!handled && this.showEmotePicker) {
+					Character c = this.emotePicker.click(mx - 2, my - (this.height - 16 - this.emotePicker.getHeight()));
 					if (c != null) {
-						editor.handleInput(0, c);
-						if (!Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) && !Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) showEmotePicker = false;
+                        this.editor.handleInput(0, c);
+						if (!Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) && !Keyboard.isKeyDown(Keyboard.KEY_RSHIFT))
+                            this.showEmotePicker = false;
 						handled = true;
 					}
 				}
@@ -279,7 +281,7 @@ public class ScreenChat extends Screen implements ITextField {
 
 	@Override
 	public String getText() {
-		return message;
+		return this.message;
 	}
 
 	@Override
@@ -289,6 +291,6 @@ public class ScreenChat extends Screen implements ITextField {
 
 	private String getMessage(int currentIndex)
 	{
-		return mc.thePlayer.messageHistory.get(mc.thePlayer.messageHistory.size()-currentIndex);
+		return this.mc.thePlayer.messageHistory.get(this.mc.thePlayer.messageHistory.size()-currentIndex);
 	}
 }
\ No newline at end of file
diff --git a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenContainerAbstract.java b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenContainerAbstract.java
index b2065988a..0b8f22128 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenContainerAbstract.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenContainerAbstract.java
@@ -10,6 +10,7 @@ import net.minecraft.client.gui.guidebook.ScreenGuidebook;
 import net.minecraft.client.gui.guidebook.GuidebookSections;
 import net.minecraft.client.gui.guidebook.search.GuidebookPageSearch;
 import net.minecraft.client.input.controller.ControllerInput;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.option.enums.DescriptionPromptEnum;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
@@ -84,7 +85,7 @@ public abstract class ScreenContainerAbstract extends Screen {
 
         final ContainerInventory containerInventory = this.mc.thePlayer.inventory;
         ItemStack grabbedItem = containerInventory.getHeldItemStack();
-        if (this.mc.gameSettings.enableItemDragging.value) {
+        if (GameSettings.ENABLE_ITEM_DRAGGING.value) {
             this.itemDragHandler.drawScreen(mx, my, partialTick);
 
             ItemStack grabbedItemOverride = this.itemDragHandler.getHeldItemRenderOverride();
@@ -105,7 +106,7 @@ public abstract class ScreenContainerAbstract extends Screen {
 
         GLRenderer.setColor4f(1.0F, 1.0F, 1.0F, 1.0F);
         if (containerInventory.getHeldItemStack() == null && slot != null && slot.hasItem()) {
-            boolean showDescription = DescriptionPromptEnum.showDescription(this.mc);
+            boolean showDescription = DescriptionPromptEnum.showDescription();
             String str = this.tooltipElement.getTooltipText(slot.getItemStack(), showDescription, slot);
             if (!str.isEmpty()) {
                 this.tooltipElement.render(str, mx, my, 8, -8);
@@ -150,12 +151,12 @@ public abstract class ScreenContainerAbstract extends Screen {
 
     public boolean checkKeybind(int slotId, int key, int mouseButton) {
         boolean cancelClick = false;
-        if (this.mc.gameSettings.keyInventory.isKeyOrMouse(key, mouseButton)) {
+        if (GameSettings.KEY_INVENTORY.isKeyOrMouse(key, mouseButton)) {
             this.mc.thePlayer.closeScreen();
             cancelClick = true;
         }
         if (slotId >= 0) {
-            if (this.mc.gameSettings.keyShowRecipe.isKeyOrMouse(key, mouseButton)) {
+            if (GameSettings.KEY_SHOW_RECIPE.isKeyOrMouse(key, mouseButton)) {
                 Slot slot = this.inventorySlots.slots.get(slotId);
                 if (slot.hasItem()) {
                     String query = "r:" + slot.getItemStack().getDisplayName() + "!";
@@ -177,7 +178,7 @@ public abstract class ScreenContainerAbstract extends Screen {
                 }
                 cancelClick = true;
             }
-            if (this.mc.gameSettings.keyShowUsage.isKeyOrMouse(key, mouseButton)) {
+            if (GameSettings.KEY_SHOW_USAGE.isKeyOrMouse(key, mouseButton)) {
                 Slot slot = this.inventorySlots.slots.get(slotId);
                 if (slot.hasItem()) {
                     String query = "u:" + slot.getItemStack().getDisplayName() + "!";
@@ -199,7 +200,7 @@ public abstract class ScreenContainerAbstract extends Screen {
                 }
                 cancelClick = true;
             }
-            if (this.mc.gameSettings.keyDrop.isKeyOrMouse(key, mouseButton)) {
+            if (GameSettings.KEY_DROP.isKeyOrMouse(key, mouseButton)) {
                 boolean ctrl = Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL);
                 int amount = 1;
                 if (ctrl) amount = 64;
@@ -207,49 +208,49 @@ public abstract class ScreenContainerAbstract extends Screen {
                 cancelClick = true;
             }
             // Horrifying
-            if (this.mc.gameSettings.keyHotBarSlot1.isKeyOrMouse(key, mouseButton)) {
+            if (GameSettings.KEY_HOT_BAR_SLOT_1.isKeyOrMouse(key, mouseButton)) {
                 this.mc.playerController.handleInventoryMouseClick(this.inventorySlots.containerId, InventoryAction.HOTBAR_ITEM_SWAP, new int[]{slotId, 1}, this.mc.thePlayer);
                 cancelClick = true;
             }
-            if (this.mc.gameSettings.keyHotBarSlot2.isKeyOrMouse(key, mouseButton)) {
+            if (GameSettings.KEY_HOT_BAR_SLOT_2.isKeyOrMouse(key, mouseButton)) {
                 this.mc.playerController.handleInventoryMouseClick(this.inventorySlots.containerId, InventoryAction.HOTBAR_ITEM_SWAP, new int[]{slotId, 2}, this.mc.thePlayer);
                 cancelClick = true;
             }
-            if (this.mc.gameSettings.keyHotBarSlot3.isKeyOrMouse(key, mouseButton)) {
+            if (GameSettings.KEY_HOT_BAR_SLOT_3.isKeyOrMouse(key, mouseButton)) {
                 this.mc.playerController.handleInventoryMouseClick(this.inventorySlots.containerId, InventoryAction.HOTBAR_ITEM_SWAP, new int[]{slotId, 3}, this.mc.thePlayer);
                 cancelClick = true;
             }
-            if (this.mc.gameSettings.keyHotBarSlot4.isKeyOrMouse(key, mouseButton)) {
+            if (GameSettings.KEY_HOT_BAR_SLOT_4.isKeyOrMouse(key, mouseButton)) {
                 this.mc.playerController.handleInventoryMouseClick(this.inventorySlots.containerId, InventoryAction.HOTBAR_ITEM_SWAP, new int[]{slotId, 4}, this.mc.thePlayer);
                 cancelClick = true;
             }
-            if (this.mc.gameSettings.keyHotBarSlot5.isKeyOrMouse(key, mouseButton)) {
+            if (GameSettings.KEY_HOT_BAR_SLOT_5.isKeyOrMouse(key, mouseButton)) {
                 this.mc.playerController.handleInventoryMouseClick(this.inventorySlots.containerId, InventoryAction.HOTBAR_ITEM_SWAP, new int[]{slotId, 5}, this.mc.thePlayer);
                 cancelClick = true;
             }
-            if (this.mc.gameSettings.keyHotBarSlot6.isKeyOrMouse(key, mouseButton)) {
+            if (GameSettings.KEY_HOT_BAR_SLOT_6.isKeyOrMouse(key, mouseButton)) {
                 this.mc.playerController.handleInventoryMouseClick(this.inventorySlots.containerId, InventoryAction.HOTBAR_ITEM_SWAP, new int[]{slotId, 6}, this.mc.thePlayer);
                 cancelClick = true;
             }
-            if (this.mc.gameSettings.keyHotBarSlot7.isKeyOrMouse(key, mouseButton)) {
+            if (GameSettings.KEY_HOT_BAR_SLOT_7.isKeyOrMouse(key, mouseButton)) {
                 this.mc.playerController.handleInventoryMouseClick(this.inventorySlots.containerId, InventoryAction.HOTBAR_ITEM_SWAP, new int[]{slotId, 7}, this.mc.thePlayer);
                 cancelClick = true;
             }
-            if (this.mc.gameSettings.keyHotBarSlot8.isKeyOrMouse(key, mouseButton)) {
+            if (GameSettings.KEY_HOT_BAR_SLOT_8.isKeyOrMouse(key, mouseButton)) {
                 this.mc.playerController.handleInventoryMouseClick(this.inventorySlots.containerId, InventoryAction.HOTBAR_ITEM_SWAP, new int[]{slotId, 8}, this.mc.thePlayer);
                 cancelClick = true;
             }
-            if (this.mc.gameSettings.keyHotBarSlot9.isKeyOrMouse(key, mouseButton)) {
+            if (GameSettings.KEY_HOT_BAR_SLOT_9.isKeyOrMouse(key, mouseButton)) {
                 this.mc.playerController.handleInventoryMouseClick(this.inventorySlots.containerId, InventoryAction.HOTBAR_ITEM_SWAP, new int[]{slotId, 9}, this.mc.thePlayer);
                 cancelClick = true;
             }
 
-            if (this.mc.gameSettings.keySortInventory.isKeyOrMouse(key, mouseButton)) {
+            if (GameSettings.KEY_SORT_INVENTORY.isKeyOrMouse(key, mouseButton)) {
                 this.mc.playerController.handleInventoryMouseClick(this.inventorySlots.containerId, InventoryAction.SORT, new int[]{slotId}, this.mc.thePlayer);
                 cancelClick = true;
             }
         }
-        if (this.mc.currentScreen == this && this.mc.gameSettings.keyGuidebook.isKeyOrMouse(key, mouseButton)) {
+        if (this.mc.currentScreen == this && GameSettings.KEY_GUIDEBOOK.isKeyOrMouse(key, mouseButton)) {
             this.mc.thePlayer.displayGuidebookScreen();
             cancelClick = true;
         }
@@ -272,7 +273,7 @@ public abstract class ScreenContainerAbstract extends Screen {
         }
         if (checkKeybind(getSlotId(mx, my), -1, buttonNum)) return;
         super.mouseClicked(mx, my, buttonNum);
-        if (this.mc.gameSettings.enableItemDragging.value) {
+        if (GameSettings.ENABLE_ITEM_DRAGGING.value) {
             this.itemDragHandler.mouseEvent(mx, my, buttonNum, true);
             return;
         }
@@ -285,7 +286,7 @@ public abstract class ScreenContainerAbstract extends Screen {
     @Override
     public void mouseReleased(int mx, int my, int buttonNum) {
         if (buttonNum >= 0) {
-            if (this.mc.gameSettings.enableItemDragging.value) {
+            if (GameSettings.ENABLE_ITEM_DRAGGING.value) {
                 this.itemDragHandler.mouseEvent(mx, my, buttonNum, false);
             }
         }
@@ -335,7 +336,7 @@ public abstract class ScreenContainerAbstract extends Screen {
             mouseButton = 0;
         }
 
-        if (this.mc.gameSettings.keySortInventory.isMouseButton(mouseButton)) {
+        if (GameSettings.KEY_SORT_INVENTORY.isMouseButton(mouseButton)) {
             action = InventoryAction.SORT;
         }
 
@@ -355,7 +356,7 @@ public abstract class ScreenContainerAbstract extends Screen {
 
         if (slot instanceof SlotResult) {
             // Crafting behavior
-            if (this.mc.gameSettings.swapCraftingButtons.value) {
+            if (GameSettings.SWAP_CRAFTING_BUTTONS.value) {
                 if (shiftPressed && ctrlPressed) {
                     action = InventoryAction.MOVE_SIMILAR;
                 } else if (shiftPressed) {
diff --git a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenFlagEditor.java b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenFlagEditor.java
index 2bccb5377..6c7fcb78b 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/container/ScreenFlagEditor.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/container/ScreenFlagEditor.java
@@ -4,6 +4,7 @@ import net.minecraft.client.gui.ButtonElement;
 import net.minecraft.client.gui.ClickableLabelElement;
 import net.minecraft.client.gui.DrawableSurfaceElement;
 import net.minecraft.client.gui.TexturedButtonElement;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.renderer.BlendFactor;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
@@ -378,7 +379,7 @@ public class ScreenFlagEditor
 
     @Override
     public void keyPressed(char eventCharacter, int eventKey, int mx, int my) {
-        if (eventKey == Keyboard.KEY_ESCAPE || this.mc.gameSettings.keyInventory.isKeyboardKey(eventKey) || eventKey == Keyboard.KEY_BACK) {
+        if (eventKey == Keyboard.KEY_ESCAPE || GameSettings.KEY_INVENTORY.isKeyboardKey(eventKey) || eventKey == Keyboard.KEY_BACK) {
             this.mc.thePlayer.closeScreen();
         }
 
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 d8f26f94f..6f7db9151 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
@@ -7,6 +7,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.option.GameSettings;
 import net.minecraft.client.render.entity.EntityRenderer;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.Shaders;
@@ -19,7 +20,6 @@ import net.minecraft.core.enums.HumanArmorShape;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.item.ItemStack;
-import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.Lighting;
 import net.minecraft.client.render.EntityRendererDispatcher;
 import net.minecraft.core.player.gamemode.Gamemodes;
@@ -39,8 +39,6 @@ public class ScreenInventory extends ScreenContainerAbstract {
     protected ListLayout overlayButtonsLayout = new ListLayout(this).setAlign(0.5, 0.5).setVertical(false).setElementSize(11, 11).setOffset(-(this.xSize / 2), -(this.ySize / 2) - 10).setMargin(1);
     private final IntList uvs = new IntArrayList();
 
-    private DamageType hoveredDamageType;
-
 
     public ScreenInventory(Player player) {
         super(player.inventoryMenu);
@@ -81,8 +79,6 @@ public class ScreenInventory extends ScreenContainerAbstract {
     }
 
     public void updateOverlayButtons() {
-        GameSettings settings = this.mc.gameSettings;
-
         boolean clock = false;
         boolean compass = false;
         boolean rotaryCalendar = false;
@@ -112,21 +108,21 @@ public class ScreenInventory extends ScreenContainerAbstract {
         this.overlayButtonsLayout.elements.clear();
 
         if (compass) {
-            this.overlayButtonsLayout.addElement(new OverlayButtonElement<>(settings, settings.overlayShowCoords));
+            this.overlayButtonsLayout.addElement(new OverlayButtonElement<>(GameSettings.OVERLAY_SHOW_COORDS));
             this.uvs.add(0);
-            this.overlayButtonsLayout.addElement(new OverlayButtonElement<>(settings, settings.overlayShowDirection));
+            this.overlayButtonsLayout.addElement(new OverlayButtonElement<>(GameSettings.OVERLAY_SHOW_DIRECTION));
             this.uvs.add(1);
         }
         if (clock) {
-            this.overlayButtonsLayout.addElement(new OverlayButtonElement<>(settings, settings.overlayShowTime));
+            this.overlayButtonsLayout.addElement(new OverlayButtonElement<>(GameSettings.OVERLAY_SHOW_TIME));
             this.uvs.add(2);
         }
         if (rotaryCalendar) {
-            this.overlayButtonsLayout.addElement(new OverlayButtonElement<>(settings, settings.overlayShowSeason));
+            this.overlayButtonsLayout.addElement(new OverlayButtonElement<>(GameSettings.OVERLAY_SHOW_SEASON));
             this.uvs.add(3);
-            this.overlayButtonsLayout.addElement(new OverlayButtonElement<>(settings, settings.overlayShowWeather));
+            this.overlayButtonsLayout.addElement(new OverlayButtonElement<>(GameSettings.OVERLAY_SHOW_WEATHER));
             this.uvs.add(4);
-            this.overlayButtonsLayout.addElement(new OverlayButtonElement<>(settings, settings.overlayShowBiome));
+            this.overlayButtonsLayout.addElement(new OverlayButtonElement<>(GameSettings.OVERLAY_SHOW_BIOME));
             this.uvs.add(5);
         }
 
@@ -150,7 +146,7 @@ public class ScreenInventory extends ScreenContainerAbstract {
         this.xSize_lo = mx;
         this.ySize_lo = my;
 
-        if (this.mc.gameSettings.armorProtectionOverlay.value && this.armorButton.enabled) {
+        if (GameSettings.ARMOR_PROTECTION_OVERLAY.value && this.armorButton.enabled) {
             drawProtectionOverlay(mx, my);
         }
         this.mc.textureManager.loadTexture("/assets/minecraft/textures/gui/container/inventory.png").bind();
@@ -190,7 +186,7 @@ public class ScreenInventory extends ScreenContainerAbstract {
 
 
     public void drawProtectionOverlay(int mouseX, int mouseY) {
-        this.hoveredDamageType = null;
+        DamageType hoveredDamageType = null;
 
         int x = this.width / 2 - this.armourValuesFloat - 4;
         int y = this.height / 2 - 79;
@@ -227,14 +223,14 @@ public class ScreenInventory extends ScreenContainerAbstract {
                 drawRectWidthHeight(x2 + 15, y2 + 4, (int) (protection * w2), h2, color);
 
                 if (mouseX >= x2 && mouseY >= y2 + 2 && mouseX <= x2 + w && mouseY <= y2 + 12) {
-                    this.hoveredDamageType = damageType;
+                    hoveredDamageType = damageType;
                 }
             }
             i++;
         }
 
-        if (this.hoveredDamageType != null) {
-            int protection = Math.round(this.mc.thePlayer.getTotalProtectionAmount(this.hoveredDamageType) * 100);
+        if (hoveredDamageType != null) {
+            int protection = Math.round(this.mc.thePlayer.getTotalProtectionAmount(hoveredDamageType) * 100);
             if (protection < 0) {
                 protection = 0;
             }
@@ -242,7 +238,7 @@ public class ScreenInventory extends ScreenContainerAbstract {
                 protection = 100;
             }
 
-            String str = I18n.getInstance().translateKey(this.hoveredDamageType.getLanguageKey()) + ":\n" + protection + " / 100";
+            String str = I18n.getInstance().translateKey(hoveredDamageType.getLanguageKey()) + ":\n" + protection + " / 100";
 
             this.tooltipElement.render(str, mouseX, mouseY, 8, -8);
         }
@@ -299,7 +295,7 @@ public class ScreenInventory extends ScreenContainerAbstract {
     @Override
     protected void buttonClicked(@NotNull ButtonElement button) {
         if (button == this.armorButton) {
-            this.mc.gameSettings.armorProtectionOverlay.toggle();
+            GameSettings.ARMOR_PROTECTION_OVERLAY.toggle();
         }
     }
 
diff --git a/game/client/src/main/java/net/minecraft/client/gui/guidebook/ScreenGuidebook.java b/game/client/src/main/java/net/minecraft/client/gui/guidebook/ScreenGuidebook.java
index c3caa69e5..abfd30032 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/guidebook/ScreenGuidebook.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/guidebook/ScreenGuidebook.java
@@ -7,6 +7,7 @@ import net.minecraft.client.gui.TooltipElement;
 import net.minecraft.client.gui.guidebook.search.GuidebookPageSearch;
 import net.minecraft.client.gui.guidebook.search.GuidebookSectionSearch;
 import net.minecraft.client.input.controller.ControllerInput;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.Lighting;
 import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.TextureManager;
@@ -295,7 +296,7 @@ public class ScreenGuidebook
             updateTabList();
         }
 
-        if (!consumedInput && this.mc.gameSettings.keyGuidebook.isKeyboardKey(eventKey)) { // If R pressed and not consumed by page exit guidebook
+        if (!consumedInput && GameSettings.KEY_GUIDEBOOK.isKeyboardKey(eventKey)) { // If R pressed and not consumed by page exit guidebook
             this.mc.displayScreen(getParentScreen());
         }
     }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/guidebook/SlotGuidebook.java b/game/client/src/main/java/net/minecraft/client/gui/guidebook/SlotGuidebook.java
index 5775a1cb2..e1bcf2f0f 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/guidebook/SlotGuidebook.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/guidebook/SlotGuidebook.java
@@ -1,7 +1,7 @@
 package net.minecraft.client.gui.guidebook;
 
-import net.minecraft.client.Minecraft;
 import net.minecraft.client.entity.player.PlayerLocal;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.core.WeightedRandomBag;
 import net.minecraft.core.WeightedRandomLootObject;
 import net.minecraft.core.achievement.stat.StatList;
@@ -19,13 +19,13 @@ import java.util.Random;
 
 public class SlotGuidebook extends Slot
 {
-	public ItemStack item;
-	public RecipeSymbol symbol;
-	public RecipeEntryBase<?,?,?> recipe;
+	public @Nullable ItemStack item;
+	public @Nullable RecipeSymbol symbol;
+	public @Nullable RecipeEntryBase<?,?,?> recipe;
 	public int recipeIndex = 0;
 	public int recipeAmount = 0;
 	public boolean isOutput = false;
-	public SlotGuidebook(final int id, final int x, final int y, final RecipeSymbol symbol, final boolean discovered, final RecipeEntryBase<?,?,?> recipe)
+	public SlotGuidebook(final int id, final int x, final int y, final @Nullable RecipeSymbol symbol, final boolean discovered, final @Nullable RecipeEntryBase<?,?,?> recipe)
 	{
 		super(null, id, x, y);
 		this.index = id;
@@ -33,10 +33,10 @@ public class SlotGuidebook extends Slot
 		if(symbol != null && symbol.getItemGroup() != null){
 			showRandomItem();
 		} else if (symbol != null) {
-			item = symbol.resolve().get(0);
-			if(recipe instanceof RecipeEntryTrommel){
-				WeightedRandomBag<WeightedRandomLootObject> loot = (WeightedRandomBag<WeightedRandomLootObject>) recipe.getOutput();
-				recipeAmount = loot.getEntries().size()-1;
+            this.item = symbol.resolve().get(0);
+			if(recipe instanceof RecipeEntryTrommel entryTrommel){
+				WeightedRandomBag<WeightedRandomLootObject> loot = entryTrommel.getOutput();
+                this.recipeAmount = loot.getEntries().size()-1;
 			}
 		}
 		this.discovered = discovered;
@@ -52,7 +52,7 @@ public class SlotGuidebook extends Slot
 		if(symbol != null && symbol.getItemGroup() != null){
 			showRandomItem();
 		} else if (symbol != null) {
-			item = symbol.resolve().get(0);
+            this.item = symbol.resolve().get(0);
 		}
 		this.discovered = discovered;
 		this.recipe = null;
@@ -72,19 +72,19 @@ public class SlotGuidebook extends Slot
 	@Override
 	public boolean hasItem()
 	{
-		return item != null;
+		return this.item != null;
 	}
 
 	@Override
 	public int getMaxStackSize()
 	{
-		return item.getMaxStackSize();
+		return this.item.getMaxStackSize();
 	}
 
 	@Override
 	public @Nullable ItemStack getItemStack()
 	{
-		return item;
+		return this.item;
 	}
 
 	@Override
@@ -103,25 +103,24 @@ public class SlotGuidebook extends Slot
     }
 
 	public void showRandomItem(){
-		if(symbol != null && symbol.getItemGroup() != null){
+		if(this.symbol != null && this.symbol.getItemGroup() != null){
 			Random r = new Random();
-			List<ItemStack> list = symbol.resolve();
+			List<ItemStack> list = this.symbol.resolve();
 			ItemStack newItem = list.get(r.nextInt(list.size()));
 			if (list.size() > 1) {
-				while (newItem == item){
+				while (newItem == this.item){
 					newItem = list.get(r.nextInt(list.size()));
 				}
 			}
-			item = newItem;
+            this.item = newItem;
 		}
 	}
 	public boolean getIsDiscovered(Player player){
-		if (item == null || discovered) return true;
+		if (this.item == null || this.discovered) return true;
 		if (player instanceof PlayerLocal){
-			Minecraft mc = Minecraft.getMinecraft();
-			if (!mc.gameSettings.hideUndiscoveredItems.value) return true;
+			if (!GameSettings.HIDE_UNDISCOVERED_ITEMS.value) return true;
 		}
-		return player.getStat(item.getItem().getStat(StatList.STAT_PICKED_UP)) > 0 || player.getGamemode() == Gamemodes.CREATIVE;
+		return player.getStat(this.item.getItem().getStat(StatList.STAT_PICKED_UP)) > 0 || player.getGamemode() == Gamemodes.CREATIVE;
 	}
 
 	public void scrollRecipe(){
diff --git a/game/client/src/main/java/net/minecraft/client/gui/guidebook/crafting/RecipePageCrafting.java b/game/client/src/main/java/net/minecraft/client/gui/guidebook/crafting/RecipePageCrafting.java
index 08887a0c9..6274f1555 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/guidebook/crafting/RecipePageCrafting.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/guidebook/crafting/RecipePageCrafting.java
@@ -20,6 +20,7 @@ import net.minecraft.client.gui.guidebook.crafting.displays.DisplayAdapterShapel
 import net.minecraft.client.gui.guidebook.crafting.displays.DisplayAdapterTool;
 import net.minecraft.client.gui.guidebook.crafting.displays.DisplayAdapterUndye;
 import net.minecraft.client.gui.guidebook.search.GuidebookPageSearch;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.option.enums.DescriptionPromptEnum;
 import net.minecraft.client.render.TextureManager;
 import net.minecraft.client.render.font.FontRenderer;
@@ -132,7 +133,7 @@ public class RecipePageCrafting
     @Override
     public boolean keyTyped(char c, int key, int x, int y, int mouseX, int mouseY) {
         super.keyTyped(c, key, x, y, mouseX, mouseY);
-        if (mc.gameSettings.keyShowRecipe.isKeyboardKey(key)) {
+        if (GameSettings.KEY_SHOW_RECIPE.isKeyboardKey(key)) {
             SlotGuidebook hoveringSlot = null;
             for (SlotGuidebook slot : this.slots) {
                 if (getIsMouseOverSlot(slot, x, y, mouseX, mouseY)) hoveringSlot = slot;
@@ -147,7 +148,7 @@ public class RecipePageCrafting
                     return true;
                 }
             }
-        } else if (mc.gameSettings.keyShowUsage.isKeyboardKey(key)) {
+        } else if (GameSettings.KEY_SHOW_USAGE.isKeyboardKey(key)) {
             SlotGuidebook hoveringSlot = null;
             for (SlotGuidebook slot : this.slots) {
                 if (getIsMouseOverSlot(slot, x, y, mouseX, mouseY)) hoveringSlot = slot;
@@ -191,7 +192,7 @@ public class RecipePageCrafting
             if (getIsMouseOverSlot(slot, x, y, mouseX, mouseY)) mouseOverSlot = slot;
             GLRenderer.setColor4f(1.0F, 1.0F, 1.0F, 1.0F);
             if (mouseOverSlot != null && mouseOverSlot.hasItem()) {
-                boolean showDescription = DescriptionPromptEnum.showDescription(mc);
+                boolean showDescription = DescriptionPromptEnum.showDescription();
                 String str = this.tooltipElement.getTooltipText(mouseOverSlot.getItemStack(), showDescription, mouseOverSlot);
                 if (!str.isEmpty()) {
                     this.tooltipElement.render(str, mouseX, mouseY, 8, -8);
diff --git a/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookPageMob.java b/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookPageMob.java
index fbe0adaa0..03c87103b 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookPageMob.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/guidebook/mobs/GuidebookPageMob.java
@@ -6,6 +6,7 @@ import net.minecraft.client.gui.ItemElement;
 import net.minecraft.client.gui.TooltipElement;
 import net.minecraft.client.gui.guidebook.GuidebookPage;
 import net.minecraft.client.gui.guidebook.GuidebookSection;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.option.enums.DescriptionPromptEnum;
 import net.minecraft.client.render.*;
 import net.minecraft.client.render.font.FontRenderer;
@@ -109,7 +110,7 @@ public class GuidebookPageMob
     protected void renderForeground(TextureManager re, FontRenderer sr, int x, int y, int mouseX, int mouseY, float partialTicks) {
         EntityDispatcher.EntityDispatcherEntry<?> entry = EntityDispatcher.getInstance().entryForClass(this.mobClass);
         this.discovered = mc.statsCounter.readStat(StatList.mobEncounterStats.get(entry != null ? entry.namespaceID : null)) > 0;
-        if (mc.thePlayer.getGamemode() == Gamemodes.CREATIVE || !mc.gameSettings.hideUndiscoveredItems.value)
+        if (mc.thePlayer.getGamemode() == Gamemodes.CREATIVE || !GameSettings.HIDE_UNDISCOVERED_ITEMS.value)
             this.discovered = true;
 
         Lighting.disable();
@@ -279,7 +280,7 @@ public class GuidebookPageMob
             if (getIsMouseOverSlot(slot, x, y, mouseX, mouseY)) mouseOverSlot = slot;
             GLRenderer.setColor4f(1.0F, 1.0F, 1.0F, 1.0F);
             if (mouseOverSlot != null && mouseOverSlot.hasItem()) {
-                boolean showDescription = DescriptionPromptEnum.showDescription(mc);
+                boolean showDescription = DescriptionPromptEnum.showDescription();
                 String str = tooltipElement.getTooltipText(mouseOverSlot.getItemStack(), showDescription, mouseOverSlot);
                 if (!str.isEmpty()) {
                     tooltipElement.render(str, mouseX, mouseY, 8, -8);
diff --git a/game/client/src/main/java/net/minecraft/client/gui/guidebook/smelting/RecipePageBlastSmelting.java b/game/client/src/main/java/net/minecraft/client/gui/guidebook/smelting/RecipePageBlastSmelting.java
index ee3eb4e8f..f9b070c9d 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/guidebook/smelting/RecipePageBlastSmelting.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/guidebook/smelting/RecipePageBlastSmelting.java
@@ -9,6 +9,7 @@ import net.minecraft.client.gui.guidebook.GuidebookSection;
 import net.minecraft.client.gui.guidebook.GuidebookSections;
 import net.minecraft.client.gui.guidebook.RecipePage;
 import net.minecraft.client.gui.guidebook.search.GuidebookPageSearch;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.option.enums.DescriptionPromptEnum;
 import net.minecraft.client.render.TextureManager;
 import net.minecraft.client.render.font.FontRenderer;
@@ -90,7 +91,7 @@ public class RecipePageBlastSmelting
     @Override
     public boolean keyTyped(char c, int key, int x, int y, int mouseX, int mouseY) {
         super.keyTyped(c, key, x, y, mouseX, mouseY);
-        if (mc.gameSettings.keyShowRecipe.isKeyboardKey(key)) {
+        if (GameSettings.KEY_SHOW_RECIPE.isKeyboardKey(key)) {
             SlotGuidebook hoveringSlot = null;
             for (SlotGuidebook slot : this.slots) {
                 if (getIsMouseOverSlot(slot, x, y, mouseX, mouseY)) hoveringSlot = slot;
@@ -105,7 +106,7 @@ public class RecipePageBlastSmelting
                     return true;
                 }
             }
-        } else if (mc.gameSettings.keyShowUsage.isKeyboardKey(key)) {
+        } else if (GameSettings.KEY_SHOW_USAGE.isKeyboardKey(key)) {
             SlotGuidebook hoveringSlot = null;
             for (SlotGuidebook slot : this.slots) {
                 if (getIsMouseOverSlot(slot, x, y, mouseX, mouseY)) hoveringSlot = slot;
@@ -149,7 +150,7 @@ public class RecipePageBlastSmelting
             if (getIsMouseOverSlot(slot, x, y, mouseX, mouseY)) mouseOverSlot = slot;
             GLRenderer.setColor4f(1.0F, 1.0F, 1.0F, 1.0F);
             if (mouseOverSlot != null && mouseOverSlot.hasItem()) {
-                boolean showDescription = DescriptionPromptEnum.showDescription(mc);
+                boolean showDescription = DescriptionPromptEnum.showDescription();
                 String str = this.tooltipElement.getTooltipText(mouseOverSlot.getItemStack(), showDescription, mouseOverSlot);
                 if (!str.isEmpty()) {
                     this.tooltipElement.render(str, mouseX, mouseY, 8, -8);
diff --git a/game/client/src/main/java/net/minecraft/client/gui/guidebook/smelting/RecipePageSmelting.java b/game/client/src/main/java/net/minecraft/client/gui/guidebook/smelting/RecipePageSmelting.java
index 7c68cde75..73c390edb 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/guidebook/smelting/RecipePageSmelting.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/guidebook/smelting/RecipePageSmelting.java
@@ -9,6 +9,7 @@ import net.minecraft.client.gui.guidebook.GuidebookSection;
 import net.minecraft.client.gui.guidebook.GuidebookSections;
 import net.minecraft.client.gui.guidebook.RecipePage;
 import net.minecraft.client.gui.guidebook.search.GuidebookPageSearch;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.option.enums.DescriptionPromptEnum;
 import net.minecraft.client.render.TextureManager;
 import net.minecraft.client.render.font.FontRenderer;
@@ -85,7 +86,7 @@ public class RecipePageSmelting
     @Override
     public boolean keyTyped(char c, int key, int x, int y, int mouseX, int mouseY) {
         super.keyTyped(c, key, x, y, mouseX, mouseY);
-        if (mc.gameSettings.keyShowRecipe.isKeyboardKey(key)) {
+        if (GameSettings.KEY_SHOW_RECIPE.isKeyboardKey(key)) {
             SlotGuidebook hoveringSlot = null;
             for (SlotGuidebook slot : this.slots) {
                 if (getIsMouseOverSlot(slot, x, y, mouseX, mouseY)) hoveringSlot = slot;
@@ -100,7 +101,7 @@ public class RecipePageSmelting
                     return true;
                 }
             }
-        } else if (mc.gameSettings.keyShowUsage.isKeyboardKey(key)) {
+        } else if (GameSettings.KEY_SHOW_USAGE.isKeyboardKey(key)) {
             SlotGuidebook hoveringSlot = null;
             for (SlotGuidebook slot : this.slots) {
                 if (getIsMouseOverSlot(slot, x, y, mouseX, mouseY)) hoveringSlot = slot;
@@ -144,7 +145,7 @@ public class RecipePageSmelting
             if (getIsMouseOverSlot(slot, x, y, mouseX, mouseY)) mouseOverSlot = slot;
             GLRenderer.setColor4f(1.0F, 1.0F, 1.0F, 1.0F);
             if (mouseOverSlot != null && mouseOverSlot.hasItem()) {
-                boolean showDescription = DescriptionPromptEnum.showDescription(mc);
+                boolean showDescription = DescriptionPromptEnum.showDescription();
                 String str = this.tooltipElement.getTooltipText(mouseOverSlot.getItemStack(), showDescription, mouseOverSlot);
                 if (!str.isEmpty()) {
                     this.tooltipElement.render(str, mouseX, mouseY, 8, -8);
diff --git a/game/client/src/main/java/net/minecraft/client/gui/guidebook/trommeling/RecipePageTrommel.java b/game/client/src/main/java/net/minecraft/client/gui/guidebook/trommeling/RecipePageTrommel.java
index e78e10646..e32768445 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/guidebook/trommeling/RecipePageTrommel.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/guidebook/trommeling/RecipePageTrommel.java
@@ -9,6 +9,7 @@ import net.minecraft.client.gui.guidebook.GuidebookSection;
 import net.minecraft.client.gui.guidebook.GuidebookSections;
 import net.minecraft.client.gui.guidebook.RecipePage;
 import net.minecraft.client.gui.guidebook.search.GuidebookPageSearch;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.option.enums.DescriptionPromptEnum;
 import net.minecraft.client.render.TextureManager;
 import net.minecraft.client.render.font.FontRenderer;
@@ -88,8 +89,8 @@ public class RecipePageTrommel
         if (ticks2 > 25) {
             ticks2 = 0;
             for (SlotGuidebook slot : this.slots) {
-                if (slot.recipe instanceof RecipeEntryTrommel) {
-                    RecipeSymbol input = (RecipeSymbol) slot.recipe.getInput();
+                if (slot.recipe instanceof RecipeEntryTrommel entryTrommel) {
+                    RecipeSymbol input = entryTrommel.getInput();
                     if (!input.matches(slot.getItemStack())) {
                         if (slot.recipeAmount > 8) {
                             int recipeIndexMax = Math.round((float) slot.recipeAmount / 9);
@@ -98,7 +99,7 @@ public class RecipePageTrommel
                             } else {
                                 slot.recipeIndex++;
                             }
-                            WeightedRandomBag<WeightedRandomLootObject> loot = (WeightedRandomBag<WeightedRandomLootObject>) slot.recipe.getOutput();
+                            WeightedRandomBag<WeightedRandomLootObject> loot = entryTrommel.getOutput();
                             int index = slot.index + (9 * slot.recipeIndex);
                             if (index > slot.recipeAmount) {
                                 slot.item = null;
@@ -132,7 +133,7 @@ public class RecipePageTrommel
     @Override
     public boolean keyTyped(char c, int key, int x, int y, int mouseX, int mouseY) {
         super.keyTyped(c, key, x, y, mouseX, mouseY);
-        if (mc.gameSettings.keyShowRecipe.isKeyboardKey(key)) {
+        if (GameSettings.KEY_SHOW_RECIPE.isKeyboardKey(key)) {
             SlotGuidebook hoveringSlot = null;
             for (SlotGuidebook slot : this.slots) {
                 if (getIsMouseOverSlot(slot, x, y, mouseX, mouseY)) hoveringSlot = slot;
@@ -147,7 +148,7 @@ public class RecipePageTrommel
                     return true;
                 }
             }
-        } else if (mc.gameSettings.keyShowUsage.isKeyboardKey(key)) {
+        } else if (GameSettings.KEY_SHOW_USAGE.isKeyboardKey(key)) {
             SlotGuidebook hoveringSlot = null;
             for (SlotGuidebook slot : this.slots) {
                 if (getIsMouseOverSlot(slot, x, y, mouseX, mouseY)) hoveringSlot = slot;
@@ -191,7 +192,7 @@ public class RecipePageTrommel
             if (getIsMouseOverSlot(slot, x, y, mouseX, mouseY)) mouseOverSlot = slot;
             GLRenderer.setColor4f(1.0F, 1.0F, 1.0F, 1.0F);
             if (mouseOverSlot != null && mouseOverSlot.hasItem()) {
-                boolean showDescription = DescriptionPromptEnum.showDescription(mc);
+                boolean showDescription = DescriptionPromptEnum.showDescription();
                 String str = this.tooltipElement.getTooltipText(mouseOverSlot.getItemStack(), showDescription, mouseOverSlot);
                 if (!str.isEmpty()) {
                     this.tooltipElement.render(str, mouseX, mouseY, 8, -8);
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 2907d5591..5982bc4c6 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
@@ -11,6 +11,7 @@ import net.minecraft.client.gui.chat.ScreenChat;
 import net.minecraft.client.gui.Gui;
 import net.minecraft.client.gui.HeldItemTooltipElement;
 import net.minecraft.client.gui.ScreenPhotoMode;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.block.model.BlockModelDispatcher;
 import net.minecraft.client.render.font.FontRenderer;
 import net.minecraft.client.render.renderer.BlendFactor;
@@ -79,7 +80,7 @@ public class HudIngame extends Gui {
     public HudIngame(Minecraft minecraft) {
         this.mc = minecraft;
         this.fontRenderer = this.mc.font;
-        this.heldItemTooltipElement = new HeldItemTooltipElement(this.mc);
+        this.heldItemTooltipElement = new HeldItemTooltipElement();
     }
 
     public void renderGameOverlay(float partialTicks, boolean flag, int mouseX, int mouseY) {
@@ -88,20 +89,20 @@ public class HudIngame extends Gui {
         I18n stringtranslate = I18n.getInstance();
         int width = this.mc.resolution.getScaledWidthScreenCoords();
         int height = this.mc.resolution.getScaledHeightScreenCoords();
-        int sp = (int) ((this.mc.gameSettings.screenPadding.value * height) / 8);
+        int sp = (int) ((GameSettings.SCREEN_PADDING.value * height) / 8);
         this.mc.worldRenderer.setupScaledResolution();
 
         GLRenderer.enableState(State.BLEND);
         GLRenderer.setBlendFunc(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA);
 
         // Render vignette
-        if (this.mc.gameSettings.immersiveMode.drawVignette() && this.mc.gameSettings.vignette.value) {
+        if (GameSettings.IMMERSIVE_MODE.drawVignette() && GameSettings.VIGNETTE.value) {
             renderVignette(this.mc.thePlayer.getBrightness(partialTicks), width, height);
         }
 
         // Render pumpkin overlay
         final ItemStack headSlotItem = this.mc.thePlayer.inventory.armorItemInSlot(HumanArmorShape.HEAD);
-        if (this.mc.gameSettings.thirdPersonView.value == 0 && headSlotItem != null && (headSlotItem.getItem() == Blocks.PUMPKIN_CARVED_IDLE.asItem() || headSlotItem.getItem() == Blocks.PUMPKIN_REDSTONE.asItem())) {
+        if (GameSettings.THIRD_PERSON_VIEW.value == 0 && headSlotItem != null && (headSlotItem.getItem() == Blocks.PUMPKIN_CARVED_IDLE.asItem() || headSlotItem.getItem() == Blocks.PUMPKIN_REDSTONE.asItem())) {
             renderPumpkinBlur(width, height);
         }
 
@@ -136,7 +137,7 @@ public class HudIngame extends Gui {
         }
 
         //Text Overlays
-        if (this.mc.gameSettings.immersiveMode.drawOverlays()) {
+        if (GameSettings.IMMERSIVE_MODE.drawOverlays()) {
             drawRecordPlayingOverlay(width, height - sp, partialTicks);
 
             boolean clock = false;
@@ -165,9 +166,9 @@ public class HudIngame extends Gui {
             }
 
             // Show Player List
-            if (!this.mc.gameSettings.showDebugScreen.value) drawPlayerList(width, height, sp);
+            if (!GameSettings.SHOW_DEBUG_SCREEN.value) drawPlayerList(width, height, sp);
 
-            if (this.mc.gameSettings.showDebugScreen.value) {
+            if (GameSettings.SHOW_DEBUG_SCREEN.value) {
                 GLRenderer.pushFrame();
                 GLRenderer.enableState(State.BLEND);
                 GLRenderer.setBlendFunc(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA);
@@ -382,12 +383,12 @@ public class HudIngame extends Gui {
             }
         }
 
-        if (this.mc.gameSettings.immersiveMode.drawChat()) {
+        if (GameSettings.IMMERSIVE_MODE.drawChat()) {
             drawChat(width, height, sp);
         }
 
         // Adding this mostly to see if the stitcher and dynamic textures are working properly
-        if (this.mc.gameSettings.keyToggleTextureAtlas.isPressed()) {
+        if (GameSettings.KEY_TOGGLE_TEXTURE_ATLAS.isPressed()) {
             GLRenderer.pushFrame();
             GLRenderer.enableState(State.BLEND);
             GLRenderer.setBlendFunc(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA);
@@ -454,10 +455,10 @@ public class HudIngame extends Gui {
 
     public void drawPlayerList(int screenWidth, int screenHeight, int screenPadding) {
         if (!this.mc.isMultiplayerWorld()) return;
-        if (this.mc.gameSettings.playerListPosition.value == 1) {
-            this.mc.gameSettings.showPlayerList.value = this.mc.gameSettings.keyPlayerList.isPressed() && this.mc.currentScreen == null;
+        if (GameSettings.PLAYER_LIST_POSITION.value == 1) {
+            GameSettings.SHOW_PLAYER_LIST.value = GameSettings.KEY_PLAYER_LIST.isPressed() && this.mc.currentScreen == null;
         }
-        if (!this.mc.gameSettings.showPlayerList.value) return;
+        if (!GameSettings.SHOW_PLAYER_LIST.value) return;
 
         if (!(this.mc.thePlayer instanceof PlayerLocalMultiplayer player)) return;
 
@@ -498,14 +499,14 @@ public class HudIngame extends Gui {
         int listX = 0;
         int listY = screenPadding;
 
-        if (this.mc.gameSettings.playerListPosition.value == 0) {
+        if (GameSettings.PLAYER_LIST_POSITION.value == 0) {
             listX = (screenWidth - width) / 2;
         }
-        if (this.mc.gameSettings.playerListPosition.value == 1) {
+        if (GameSettings.PLAYER_LIST_POSITION.value == 1) {
             listX = (screenWidth - width) / 2;
             listY = screenHeight / 6 + screenPadding;
         }
-        if (this.mc.gameSettings.playerListPosition.value == 2) {
+        if (GameSettings.PLAYER_LIST_POSITION.value == 2) {
             listX = screenWidth - width - screenPadding;
         }
 
@@ -551,7 +552,7 @@ public class HudIngame extends Gui {
     }
 
     public void drawChat(int width, int height, int sp) {
-        if (this.mc.gameSettings.chatVisibility.value == ChatVisibility.NEVER_SHOW) return;
+        if (GameSettings.chatVisibility.value == ChatVisibility.NEVER_SHOW) return;
 //        if(mc.currentScreen instanceof ScreenChat && ((ScreenChat) mc.currentScreen).message.startsWith("/")) return;
         int linesToShow = 10;
         boolean ignoreFadeout = false;
@@ -559,7 +560,7 @@ public class HudIngame extends Gui {
             int acceptableSize = height - 48 - 48;
             linesToShow = acceptableSize / 9;
             ignoreFadeout = true;
-        } else if (this.mc.gameSettings.chatVisibility.value == ChatVisibility.SHOW_WHEN_CHATTING) {
+        } else if (GameSettings.chatVisibility.value == ChatVisibility.SHOW_WHEN_CHATTING) {
             return;
         }
 
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngameDoom.java b/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngameDoom.java
index 3afee5d6a..360bb0453 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngameDoom.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/HudIngameDoom.java
@@ -4,6 +4,7 @@ import it.unimi.dsi.fastutil.ints.IntArrayList;
 import it.unimi.dsi.fastutil.ints.IntList;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.ScreenPhotoMode;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.renderer.BlendFactor;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
@@ -39,13 +40,13 @@ public class HudIngameDoom
         GLRenderer.setBlendFunc(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA);
 
         // Render vignette
-        if (this.mc.gameSettings.immersiveMode.drawVignette() && this.mc.gameSettings.vignette.value) {
+        if (GameSettings.IMMERSIVE_MODE.drawVignette() && GameSettings.VIGNETTE.value) {
             renderVignette(this.mc.thePlayer.getBrightness(partialTicks), width, height);
         }
 
         // Render pumpkin overlay
         ItemStack headSlotItem = this.mc.thePlayer.getItemInArmorSlot(HumanArmorShape.HEAD);
-        if (this.mc.gameSettings.thirdPersonView.value == 0 && headSlotItem != null && (headSlotItem.getItem() == Blocks.PUMPKIN_CARVED_IDLE.asItem() || headSlotItem.itemID == Blocks.PUMPKIN_REDSTONE.id())) {
+        if (GameSettings.THIRD_PERSON_VIEW.value == 0 && headSlotItem != null && (headSlotItem.getItem() == Blocks.PUMPKIN_CARVED_IDLE.asItem() || headSlotItem.itemID == Blocks.PUMPKIN_REDSTONE.id())) {
             renderPumpkinBlur(width, height);
         }
 
@@ -66,7 +67,7 @@ public class HudIngameDoom
 
         GLRenderer.setColor4f(1.0F, 1.0F, 1.0F, 1.0F);
 
-        if (this.mc.gameSettings.immersiveMode.drawCrosshair() && this.mc.gameSettings.thirdPersonView.value == 0) {
+        if (GameSettings.IMMERSIVE_MODE.drawCrosshair() && GameSettings.THIRD_PERSON_VIEW.value == 0) {
             // Render crosshair
             GLRenderer.enableState(State.BLEND);
             GLRenderer.setBlendFunc(BlendFactor.ONE_MINUS_DST_COLOR, BlendFactor.ONE_MINUS_SRC_COLOR);
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentArmorBar.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentArmorBar.java
index efc1934d2..ef42eac39 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentArmorBar.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentArmorBar.java
@@ -3,6 +3,7 @@ package net.minecraft.client.gui.hud.component;
 import net.minecraft.client.gui.Gui;
 import net.minecraft.client.gui.hud.HudIngame;
 import net.minecraft.client.gui.hud.component.layout.Layout;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
@@ -23,7 +24,7 @@ public class HudComponentArmorBar
 
     @Override
     public boolean isVisible() {
-        return mc.gameSettings.immersiveMode.drawHotbar() && mc.thePlayer.getPlayerProtectionAmount() > 0;
+        return GameSettings.IMMERSIVE_MODE.drawHotbar() && mc.thePlayer.getPlayerProtectionAmount() > 0;
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentArmorDurability.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentArmorDurability.java
index 306b6607d..06a5c0a1b 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentArmorDurability.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentArmorDurability.java
@@ -3,6 +3,7 @@ package net.minecraft.client.gui.hud.component;
 import net.minecraft.client.gui.Gui;
 import net.minecraft.client.gui.hud.HudIngame;
 import net.minecraft.client.gui.hud.component.layout.Layout;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.item.model.ItemModelDispatcher;
 import net.minecraft.client.render.renderer.GLRenderer;
@@ -25,12 +26,12 @@ public class HudComponentArmorDurability
 
     @Override
     public boolean isVisible() {
-        return mc.gameSettings.immersiveMode.drawOverlays() && mc.gameSettings.armorDurabilityOverlay.value;
+        return GameSettings.IMMERSIVE_MODE.drawOverlays() && GameSettings.ARMOR_DURABILITY_OVERLAY.value;
     }
 
     @Override
     public boolean isEnabled() {
-        return mc.gameSettings.armorDurabilityOverlay.value;
+        return GameSettings.ARMOR_DURABILITY_OVERLAY.value;
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentCrosshair.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentCrosshair.java
index 525ae7d04..62d4e9c69 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentCrosshair.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentCrosshair.java
@@ -3,6 +3,7 @@ package net.minecraft.client.gui.hud.component;
 import net.minecraft.client.gui.Gui;
 import net.minecraft.client.gui.hud.HudIngame;
 import net.minecraft.client.gui.hud.component.layout.Layout;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.renderer.BlendFactor;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
@@ -16,7 +17,7 @@ public class HudComponentCrosshair
 
     @Override
     public boolean isVisible() {
-        return mc.gameSettings.immersiveMode.drawCrosshair() && mc.gameSettings.thirdPersonView.value == 0;
+        return GameSettings.IMMERSIVE_MODE.drawCrosshair() && GameSettings.THIRD_PERSON_VIEW.value == 0;
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentFireBar.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentFireBar.java
index 0b34a6071..62da02c17 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentFireBar.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentFireBar.java
@@ -3,6 +3,7 @@ package net.minecraft.client.gui.hud.component;
 import net.minecraft.client.gui.Gui;
 import net.minecraft.client.gui.hud.HudIngame;
 import net.minecraft.client.gui.hud.component.layout.Layout;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
@@ -15,7 +16,7 @@ public class HudComponentFireBar
 
     @Override
     public boolean isVisible() {
-        return mc.gameSettings.immersiveMode.drawHotbar() && !mc.thePlayer.getGamemode().hasInvulnerablePlayer() && mc.thePlayer.remainingFireTicks > 0;
+        return GameSettings.IMMERSIVE_MODE.drawHotbar() && !mc.thePlayer.getGamemode().hasInvulnerablePlayer() && mc.thePlayer.remainingFireTicks > 0;
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHealthBar.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHealthBar.java
index 294532b28..3e16b341e 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHealthBar.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHealthBar.java
@@ -3,6 +3,7 @@ package net.minecraft.client.gui.hud.component;
 import net.minecraft.client.gui.Gui;
 import net.minecraft.client.gui.hud.HudIngame;
 import net.minecraft.client.gui.hud.component.layout.Layout;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
@@ -26,7 +27,7 @@ public class HudComponentHealthBar
 
     @Override
     public boolean isVisible() {
-        return !mc.thePlayer.getGamemode().hasInvulnerablePlayer() && mc.gameSettings.immersiveMode.drawHotbar();
+        return !mc.thePlayer.getGamemode().hasInvulnerablePlayer() && GameSettings.IMMERSIVE_MODE.drawHotbar();
     }
 
     @Override
@@ -78,7 +79,7 @@ public class HudComponentHealthBar
                 hud.drawGuiIcon(xHeart, yHeart, 9, 9, TextureRegistry.getTexture("minecraft:gui/hud/heart/" + (isHardcore ? "hardcore_" : "") + "half"));
             }
 
-            if (mc.gameSettings.foodHealthRegenOverlay.value) {
+            if (GameSettings.FOOD_HEALTH_REGEN_OVERLAY.value) {
                 int healing = 0;
                 ItemStack held = mc.thePlayer.getHeldItem();
                 if (held != null) {
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHeldItemCount.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHeldItemCount.java
index 070a574ca..6c76c10c4 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHeldItemCount.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHeldItemCount.java
@@ -3,6 +3,7 @@ package net.minecraft.client.gui.hud.component;
 import net.minecraft.client.gui.Gui;
 import net.minecraft.client.gui.hud.HudIngame;
 import net.minecraft.client.gui.hud.component.layout.Layout;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.Lighting;
 import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.item.model.ItemModelDispatcher;
@@ -23,12 +24,12 @@ public class HudComponentHeldItemCount
 
     @Override
     public boolean isVisible() {
-        return mc.gameSettings.immersiveMode.drawOverlays() && mc.gameSettings.heldItemCountOverlay.value;
+        return GameSettings.IMMERSIVE_MODE.drawOverlays() && GameSettings.HELD_ITEM_COUNT_OVERLAY.value;
     }
 
     @Override
     public boolean isEnabled() {
-        return mc.gameSettings.heldItemCountOverlay.value;
+        return GameSettings.HELD_ITEM_COUNT_OVERLAY.value;
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHotbar.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHotbar.java
index 1872d0e93..546d10460 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHotbar.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentHotbar.java
@@ -4,6 +4,7 @@ import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.Gui;
 import net.minecraft.client.gui.hud.HudIngame;
 import net.minecraft.client.gui.hud.component.layout.Layout;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.Lighting;
 import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.Scissor;
@@ -50,7 +51,7 @@ public class HudComponentHotbar
 
     @Override
     public boolean isVisible() {
-        return mc.gameSettings.immersiveMode.drawHotbar();
+        return GameSettings.IMMERSIVE_MODE.drawHotbar();
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentInfoOverlay.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentInfoOverlay.java
index aefc6f87c..1ba7ed0f5 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentInfoOverlay.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentInfoOverlay.java
@@ -5,6 +5,7 @@ import net.minecraft.client.gui.hud.HudIngame;
 import net.minecraft.client.gui.hud.component.layout.Layout;
 import net.minecraft.client.gui.hud.component.layout.LayoutAbsolute;
 import net.minecraft.client.gui.hud.component.layout.LayoutSnap;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.core.Global;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.item.Items;
@@ -12,8 +13,8 @@ import net.minecraft.core.lang.I18n;
 import net.minecraft.core.net.command.TextFormatting;
 import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.util.helper.Direction;
-import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.biome.Biomes;
+import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.season.Season;
 import net.minecraft.core.world.season.Seasons;
 import net.minecraft.core.world.weather.Weather;
@@ -29,7 +30,7 @@ public class HudComponentInfoOverlay
 
     @Override
     public boolean isVisible() {
-        return mc.gameSettings.immersiveMode.drawOverlays() && !mc.gameSettings.showDebugScreen.value;
+        return GameSettings.IMMERSIVE_MODE.drawOverlays() && !GameSettings.SHOW_DEBUG_SCREEN.value;
     }
 
     private void drawString(String string, int x, int y, int argb, boolean rightAligned) {
@@ -52,8 +53,7 @@ public class HudComponentInfoOverlay
             if (anchor == ComponentAnchor.TOP_RIGHT || anchor == ComponentAnchor.CENTER_RIGHT || anchor == ComponentAnchor.BOTTOM_RIGHT) {
                 rightAligned = true;
             }
-        } else if (this.getLayout() instanceof LayoutSnap) {
-            final LayoutSnap layout = (LayoutSnap) this.getLayout();
+        } else if (this.getLayout() instanceof LayoutSnap layout) {
             final ComponentAnchor anchor = layout.getAnchor();
             if (anchor == ComponentAnchor.TOP_RIGHT || anchor == ComponentAnchor.CENTER_RIGHT || anchor == ComponentAnchor.BOTTOM_RIGHT) {
                 rightAligned = true;
@@ -89,67 +89,64 @@ public class HudComponentInfoOverlay
         int line = 0;
         int lineHeight = 10;
 
-        if (mc.gameSettings.versionInOverlay.value) {
+        if (GameSettings.VERSION_IN_OVERLAY.value) {
             int color;
-            if (mc.gameSettings.overlayMode.value == 2) {
+            if (GameSettings.OVERLAY_MODE.value == 2) {
                 color = 0xFFFFFF60;
             } else {
                 color = 0xFFFFFFFF;
             }
             drawString("Better than Adventure! " + TextFormatting.WHITE + Global.VERSION, x, y + tsp + lineHeight * line++, color, rightAligned);
         }
-        if (mc.gameSettings.fpsInOverlay.value) {
+        if (GameSettings.FPS_IN_OVERLAY.value) {
             drawString(mc.lingDebugFPS, x, y + tsp + lineHeight * line++, 0xFFFFFFFF, rightAligned);
         }
         if (compass) {
-            if (mc.gameSettings.overlayShowCoords.value) {
-                if (mc.gameSettings.overlayMode.value == 0) {
+            if (GameSettings.OVERLAY_SHOW_COORDS.value) {
+                if (GameSettings.OVERLAY_MODE.value == 0) {
                     drawString("x: " + floor10(mc.thePlayer.x) + " y: " + floor10(mc.thePlayer.y) + " z: " + floor10(mc.thePlayer.z), x, y + tsp + lineHeight * line++, 0xFFFFFFFF, rightAligned);
                 }
-                if (mc.gameSettings.overlayMode.value == 1) {
+                if (GameSettings.OVERLAY_MODE.value == 1) {
                     drawString("x: " + floor10(mc.thePlayer.x), x, y + tsp + lineHeight * line++, 0xFFFFFFFF, rightAligned);
                     drawString("y: " + floor10(mc.thePlayer.y), x, y + tsp + lineHeight * line++, 0xFFFFFFFF, rightAligned);
                     drawString("z: " + floor10(mc.thePlayer.z), x, y + tsp + lineHeight * line++, 0xFFFFFFFF, rightAligned);
                 }
-                if (mc.gameSettings.overlayMode.value == 2) {
+                if (GameSettings.OVERLAY_MODE.value == 2) {
                     drawString("x: " + floor10(mc.thePlayer.x), x, y + tsp + lineHeight * line++, 0xFFFF8080, rightAligned);
                     drawString("y: " + floor10(mc.thePlayer.y), x, y + tsp + lineHeight * line++, 0xFF80FF80, rightAligned);
                     drawString("z: " + floor10(mc.thePlayer.z), x, y + tsp + lineHeight * line++, 0xFF8080FF, rightAligned);
                 }
             }
-            if (mc.gameSettings.overlayShowDirection.value) {
+            if (GameSettings.OVERLAY_SHOW_DIRECTION.value) {
                 drawString(I18n.getInstance().translateKey(HudIngame.getFacingDirection(mc.thePlayer).getTranslationKey()), x, y + tsp + lineHeight * line++, 0xFFFFFFFF, rightAligned);
             }
         }
         if (clock) {
-            if (mc.gameSettings.overlayShowTime.value) {
-                if (mc.gameSettings.overlayMode.value == 0) {
-                    drawString(String.format("%s %s %d", HudIngame.getTimeString(mc), I18n.getInstance().translateKey("unit.day"), mc.currentWorld.getWorldTime() / Global.DAY_LENGTH_TICKS), x, y + tsp + lineHeight * line++, mc.gameSettings.overlayMode.value == 2 ? 0xFFFFFF80 : 0xFFFFFFFF, rightAligned);
+            if (GameSettings.OVERLAY_SHOW_TIME.value) {
+                if (GameSettings.OVERLAY_MODE.value == 0) {
+                    drawString(String.format("%s %s %d", HudIngame.getTimeString(mc), I18n.getInstance().translateKey("unit.day"), mc.currentWorld.getWorldTime() / Global.DAY_LENGTH_TICKS), x, y + tsp + lineHeight * line++, GameSettings.OVERLAY_MODE.value == 2 ? 0xFFFFFF80 : 0xFFFFFFFF, rightAligned);
                 }
-                if (mc.gameSettings.overlayMode.value > 0) {
-                    drawString(HudIngame.getTimeString(mc), x, y + tsp + lineHeight * line++, mc.gameSettings.overlayMode.value == 2 ? 0xFFFFFF80 : 0xFFFFFFFF, rightAligned);
-                    drawString(String.format("%s %d", I18n.getInstance().translateKey("unit.day"), mc.currentWorld.getWorldTime() / Global.DAY_LENGTH_TICKS), x, y + tsp + lineHeight * line++, mc.gameSettings.overlayMode.value == 2 ? 0xFFFFFF80 : 0xFFFFFFFF, rightAligned);
+                if (GameSettings.OVERLAY_MODE.value > 0) {
+                    drawString(HudIngame.getTimeString(mc), x, y + tsp + lineHeight * line++, GameSettings.OVERLAY_MODE.value == 2 ? 0xFFFFFF80 : 0xFFFFFFFF, rightAligned);
+                    drawString(String.format("%s %d", I18n.getInstance().translateKey("unit.day"), mc.currentWorld.getWorldTime() / Global.DAY_LENGTH_TICKS), x, y + tsp + lineHeight * line++, GameSettings.OVERLAY_MODE.value == 2 ? 0xFFFFFF80 : 0xFFFFFFFF, rightAligned);
                 }
             }
         }
         if (rotaryCalendar) {
-            if (mc.gameSettings.overlayShowSeason.value) {
+            if (GameSettings.OVERLAY_SHOW_SEASON.value) {
                 Season season = mc.currentWorld.getSeasonManager().getCurrentSeason();
                 if (season != null) {
-                    drawString(season.getTranslatedName(), x, y + tsp + lineHeight * line++, mc.gameSettings.overlayMode.value == 2 ? 0xFF80FFFF : 0xFFFFFFFF, rightAligned);
+                    drawString(season.getTranslatedName(), x, y + tsp + lineHeight * line++, GameSettings.OVERLAY_MODE.value == 2 ? 0xFF80FFFF : 0xFFFFFFFF, rightAligned);
                 }
             }
-            if (mc.gameSettings.overlayShowWeather.value) {
+            if (GameSettings.OVERLAY_SHOW_WEATHER.value) {
                 Weather weather = mc.currentWorld.getCurrentWeather();
                 if (weather != null && weather != mc.currentWorld.worldType.getDefaultWeather()) {
-                    drawString(I18n.getInstance().translateKey(weather.getNameLanguageKey()), x, y + tsp + lineHeight * line++, mc.gameSettings.overlayMode.value == 2 ? 0xFFFF80FF : 0xFFFFFFFF, rightAligned);
+                    drawString(I18n.getInstance().translateKey(weather.getNameLanguageKey()), x, y + tsp + lineHeight * line++, GameSettings.OVERLAY_MODE.value == 2 ? 0xFFFF80FF : 0xFFFFFFFF, rightAligned);
                 }
             }
-            if (mc.gameSettings.overlayShowBiome.value) {
-                int blockX = MathHelper.floor(mc.thePlayer.x);
-                int blockY = MathHelper.floor(mc.thePlayer.y);
-                int blockZ = MathHelper.floor(mc.thePlayer.z);
-                String key = mc.currentWorld.getBlockBiome(blockX, blockY, blockZ).translationKey;
+            if (GameSettings.OVERLAY_SHOW_BIOME.value) {
+                String key = mc.currentWorld.getBlockBiome(new TilePos(mc.thePlayer)).translationKey;
                 drawString(I18n.getInstance().translateKey(key), x, y + tsp + lineHeight * line++, 0xFFFFFFFF, rightAligned);
             }
         }
@@ -188,15 +185,15 @@ public class HudComponentInfoOverlay
                 final double py = 64.355;
                 final double pz = 38472.333;
 
-                if (mc.gameSettings.overlayMode.value == 0) {
+                if (GameSettings.OVERLAY_MODE.value == 0) {
                     drawString("x: " + floor10(px) + " y: " + floor10(py) + " z: " + floor10(pz), x, y + tsp + lineHeight * line++, 0xFFFFFFFF, rightAligned);
                 }
-                if (mc.gameSettings.overlayMode.value == 1) {
+                if (GameSettings.OVERLAY_MODE.value == 1) {
                     drawString("x: " + floor10(px), x, y + tsp + lineHeight * line++, 0xFFFFFFFF, rightAligned);
                     drawString("y: " + floor10(py), x, y + tsp + lineHeight * line++, 0xFFFFFFFF, rightAligned);
                     drawString("z: " + floor10(pz), x, y + tsp + lineHeight * line++, 0xFFFFFFFF, rightAligned);
                 }
-                if (mc.gameSettings.overlayMode.value == 2) {
+                if (GameSettings.OVERLAY_MODE.value == 2) {
                     drawString("x: " + floor10(px), x, y + tsp + lineHeight * line++, 0xFFFF8080, rightAligned);
                     drawString("y: " + floor10(py), x, y + tsp + lineHeight * line++, 0xFF80FF80, rightAligned);
                     drawString("z: " + floor10(pz), x, y + tsp + lineHeight * line++, 0xFF8080FF, rightAligned);
@@ -208,23 +205,23 @@ public class HudComponentInfoOverlay
         }
         {
             {
-                if (mc.gameSettings.overlayMode.value == 0) {
-                    drawString(String.format("%s %s %d", "8:32", I18n.getInstance().translateKey("unit.day"), 500), x, y + tsp + lineHeight * line++, mc.gameSettings.overlayMode.value == 2 ? 0xFFFFFF80 : 0xFFFFFFFF, rightAligned);
+                if (GameSettings.OVERLAY_MODE.value == 0) {
+                    drawString(String.format("%s %s %d", "8:32", I18n.getInstance().translateKey("unit.day"), 500), x, y + tsp + lineHeight * line++, GameSettings.OVERLAY_MODE.value == 2 ? 0xFFFFFF80 : 0xFFFFFFFF, rightAligned);
                 }
-                if (mc.gameSettings.overlayMode.value > 0) {
-                    drawString("8:32", x, y + tsp + lineHeight * line++, mc.gameSettings.overlayMode.value == 2 ? 0xFFFFFF80 : 0xFFFFFFFF, rightAligned);
-                    drawString(String.format("%s %d", I18n.getInstance().translateKey("unit.day"), 500), x, y + tsp + lineHeight * line++, mc.gameSettings.overlayMode.value == 2 ? 0xFFFFFF80 : 0xFFFFFFFF, rightAligned);
+                if (GameSettings.OVERLAY_MODE.value > 0) {
+                    drawString("8:32", x, y + tsp + lineHeight * line++, GameSettings.OVERLAY_MODE.value == 2 ? 0xFFFFFF80 : 0xFFFFFFFF, rightAligned);
+                    drawString(String.format("%s %d", I18n.getInstance().translateKey("unit.day"), 500), x, y + tsp + lineHeight * line++, GameSettings.OVERLAY_MODE.value == 2 ? 0xFFFFFF80 : 0xFFFFFFFF, rightAligned);
                 }
             }
         }
         {
             {
                 Season season = Seasons.OVERWORLD_SUMMER;
-                drawString(season.getTranslatedName(), x, y + tsp + lineHeight * line++, mc.gameSettings.overlayMode.value == 2 ? 0xFF80FFFF : 0xFFFFFFFF, rightAligned);
+                drawString(season.getTranslatedName(), x, y + tsp + lineHeight * line++, GameSettings.OVERLAY_MODE.value == 2 ? 0xFF80FFFF : 0xFFFFFFFF, rightAligned);
             }
             {
                 Weather weather = Weathers.OVERWORLD_FOG;
-                drawString(I18n.getInstance().translateKey(weather.getNameLanguageKey()), x, y + tsp + lineHeight * line++, mc.gameSettings.overlayMode.value == 2 ? 0xFFFF80FF : 0xFFFFFFFF, rightAligned);
+                drawString(I18n.getInstance().translateKey(weather.getNameLanguageKey()), x, y + tsp + lineHeight * line++, GameSettings.OVERLAY_MODE.value == 2 ? 0xFFFF80FF : 0xFFFFFFFF, rightAligned);
             }
             {
                 String key = Biomes.OVERWORLD_GRASSLANDS.translationKey;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentLog.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentLog.java
index fe82a2ace..455b1e9a7 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentLog.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentLog.java
@@ -7,6 +7,7 @@ import net.minecraft.client.gui.hud.HudIngame;
 import net.minecraft.client.gui.hud.component.layout.Layout;
 import net.minecraft.client.gui.hud.component.layout.LayoutAbsolute;
 import net.minecraft.client.gui.hud.component.layout.LayoutSnap;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.font.FontRenderer;
 import net.minecraft.client.render.renderer.BlendFactor;
 import net.minecraft.client.render.renderer.GLRenderer;
@@ -65,12 +66,12 @@ public class HudComponentLog extends HudComponentMovable {
 
     @Override
     public boolean isEnabled() {
-        return mc.gameSettings.developerMode.value;
+        return GameSettings.DEVELOPER_MODE.value;
     }
 
     @Override
     public boolean isVisible() {
-        return mc.gameSettings.developerMode.value;
+        return GameSettings.DEVELOPER_MODE.value;
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentOxygenBar.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentOxygenBar.java
index b04117d28..473b48cf0 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentOxygenBar.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentOxygenBar.java
@@ -3,6 +3,7 @@ package net.minecraft.client.gui.hud.component;
 import net.minecraft.client.gui.Gui;
 import net.minecraft.client.gui.hud.HudIngame;
 import net.minecraft.client.gui.hud.component.layout.Layout;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
@@ -23,7 +24,7 @@ public class HudComponentOxygenBar
 
     @Override
     public boolean isVisible() {
-        return mc.gameSettings.immersiveMode.drawHotbar() && !mc.thePlayer.getGamemode().hasInvulnerablePlayer() && mc.thePlayer.isUnderLiquid(Materials.WATER);
+        return GameSettings.IMMERSIVE_MODE.drawHotbar() && !mc.thePlayer.getGamemode().hasInvulnerablePlayer() && mc.thePlayer.isUnderLiquid(Materials.WATER);
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentRotationLock.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentRotationLock.java
index 764d3468e..5a3c03019 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentRotationLock.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentRotationLock.java
@@ -3,6 +3,7 @@ package net.minecraft.client.gui.hud.component;
 import net.minecraft.client.gui.Gui;
 import net.minecraft.client.gui.hud.HudIngame;
 import net.minecraft.client.gui.hud.component.layout.Layout;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
@@ -17,7 +18,7 @@ public class HudComponentRotationLock
 
     @Override
     public boolean isVisible() {
-        return mc.thePlayer.rotationLock != null && mc.thePlayer.rotationLock != Direction.NONE && mc.gameSettings.immersiveMode.drawOverlays();
+        return mc.thePlayer.rotationLock != null && mc.thePlayer.rotationLock != Direction.NONE && GameSettings.IMMERSIVE_MODE.drawOverlays();
     }
 
     @Override
@@ -29,7 +30,7 @@ public class HudComponentRotationLock
         int x = this.getLayout().getComponentX(this, xSizeScreen);
         int y = this.getLayout().getComponentY(this, ySizeScreen);
 
-        String prefix = mc.gameSettings.rotationOverlayMode.value % 2 == 1 ? "arrow" : "cube";
+        String prefix = GameSettings.ROTATION_OVERLAY_MODE.value % 2 == 1 ? "arrow" : "cube";
 
         Player player = mc.thePlayer;
 
@@ -81,7 +82,7 @@ public class HudComponentRotationLock
         GLRenderer.setColor4f(1.0f, 1.0f, 1.0f, 1.0f); // Reset color
         GLRenderer.enableState(State.BLEND);
 
-        String prefix = mc.gameSettings.rotationOverlayMode.value % 2 == 1 ? "arrow" : "cube";
+        String prefix = GameSettings.ROTATION_OVERLAY_MODE.value % 2 == 1 ? "arrow" : "cube";
 
         gui.drawGuiIcon(x, y, 16, 16, TextureRegistry.getTexture("minecraft:gui/hud/rotation/" + prefix + "_front"));
         gui.drawGuiIcon(x + 16, y + 4, 8, 8, TextureRegistry.getTexture("minecraft:gui/hud/rotation/" + prefix + "_downer"));
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentSubtitles.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentSubtitles.java
index d458922b9..db97755eb 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentSubtitles.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentSubtitles.java
@@ -4,6 +4,7 @@ import net.minecraft.client.gui.Gui;
 import net.minecraft.client.gui.hud.HudIngame;
 import net.minecraft.client.gui.hud.component.layout.Layout;
 import net.minecraft.client.gui.subtitles.SubtitleTracker;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.renderer.BlendFactor;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
@@ -19,12 +20,12 @@ public class HudComponentSubtitles extends HudComponentMovable {
 
     @Override
     public boolean isVisible() {
-        return mc.gameSettings.immersiveMode.drawOverlays() && mc.gameSettings.subtitles.value;
+        return GameSettings.IMMERSIVE_MODE.drawOverlays() && GameSettings.SUBTITLES.value;
     }
 
     @Override
     public boolean isEnabled() {
-        return mc.gameSettings.subtitles.value;
+        return GameSettings.SUBTITLES.value;
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentVehicleHealthBar.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentVehicleHealthBar.java
index 3ab76caad..f374690da 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentVehicleHealthBar.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponentVehicleHealthBar.java
@@ -3,6 +3,7 @@ package net.minecraft.client.gui.hud.component;
 import net.minecraft.client.gui.Gui;
 import net.minecraft.client.gui.hud.HudIngame;
 import net.minecraft.client.gui.hud.component.layout.Layout;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
@@ -21,7 +22,7 @@ public class HudComponentVehicleHealthBar
 
     @Override
     public boolean isVisible() {
-        return mc.thePlayer.vehicle instanceof Mob && mc.gameSettings.immersiveMode.drawHotbar();
+        return mc.thePlayer.vehicle instanceof Mob && GameSettings.IMMERSIVE_MODE.drawHotbar();
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponents.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponents.java
index 50cd463ff..314969c03 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponents.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/HudComponents.java
@@ -3,6 +3,8 @@ package net.minecraft.client.gui.hud.component;
 import com.mojang.logging.LogUtils;
 import net.minecraft.client.gui.hud.component.layout.LayoutAbsolute;
 import net.minecraft.client.gui.hud.component.layout.LayoutSnap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
 
 import java.util.ArrayList;
@@ -12,7 +14,21 @@ public class HudComponents {
     private static final Logger LOGGER = LogUtils.getLogger();
 
     public static String DEFAULT_LAYOUT = null;
-    public static final HudComponents INSTANCE = new HudComponents();
+    public static final @Nullable HudComponents INSTANCE = new HudComponents();
+
+    public static final @NotNull HudComponent HOTBAR = register(new HudComponentHotbar("hotbar", new LayoutAbsolute(0.5f, 1.0f, ComponentAnchor.BOTTOM_CENTER)));
+    public static final @NotNull HudComponent CROSSHAIR = register(new HudComponentCrosshair("crosshair", new LayoutAbsolute(0.5f, 0.5f, ComponentAnchor.CENTER)));
+    public static final @NotNull HudComponent HEALTH_BAR = register(new HudComponentHealthBar("health_bar", new LayoutSnap(HOTBAR, ComponentAnchor.TOP_LEFT, ComponentAnchor.BOTTOM_LEFT)));
+    //    public static final HudComponent ARMOR_BAR = register(new HudComponentArmorBar("armor_bar", new LayoutSnap(HOTBAR, ComponentAnchor.TOP_RIGHT, ComponentAnchor.BOTTOM_RIGHT)));
+    public static final @NotNull HudComponent VEHICLE_BAR = register(new HudComponentVehicleHealthBar("vehicle_bar", new LayoutSnap(HOTBAR, ComponentAnchor.TOP_RIGHT, ComponentAnchor.BOTTOM_RIGHT)));
+    public static final @NotNull HudComponent OXYGEN_BAR = register(new HudComponentOxygenBar("oxygen_bar", new LayoutSnap(HEALTH_BAR, ComponentAnchor.TOP_LEFT, ComponentAnchor.BOTTOM_LEFT)));
+    public static final @NotNull HudComponent FIRE_BAR = register(new HudComponentFireBar("fire_bar", new LayoutSnap(OXYGEN_BAR, ComponentAnchor.TOP_LEFT, ComponentAnchor.BOTTOM_LEFT)));
+    public static final @NotNull HudComponent ROTATION_LOCK = register(new HudComponentRotationLock("rotation_lock", new LayoutSnap(CROSSHAIR, ComponentAnchor.CENTER_RIGHT, ComponentAnchor.CENTER_LEFT)));
+    public static final @NotNull HudComponent SUBTITLES = register(new HudComponentSubtitles("subtitles_box", 100, 50, new LayoutAbsolute(1.0f, 0.75f, ComponentAnchor.BOTTOM_RIGHT)));
+    public static final @NotNull HudComponent LOG = register(new HudComponentLog("log", new LayoutAbsolute(1.0f, 0.0f, ComponentAnchor.TOP_RIGHT)));
+    public static final @NotNull HudComponent ARMOR_DURABILITY = register(new HudComponentArmorDurability("armor_durability", new LayoutAbsolute(0.0f, 1.0f, ComponentAnchor.BOTTOM_LEFT)));
+    public static final @NotNull HudComponent HELD_ITEM_COUNT = register(new HudComponentHeldItemCount("held_item_count", new LayoutSnap(HOTBAR, ComponentAnchor.CENTER_RIGHT, ComponentAnchor.CENTER_LEFT)));
+    public static final @NotNull HudComponent INFO_OVERLAY = register(new HudComponentInfoOverlay("info_overlay", new LayoutAbsolute(0.0f, 0.0f, ComponentAnchor.TOP_LEFT)));
 
     public static HudComponent register(HudComponent component) {
         INSTANCE.components.add(component);
@@ -21,14 +37,15 @@ public class HudComponents {
     private final List<HudComponent> components = new ArrayList<>();
 
 
+
     private HudComponents() { }
 
     public List<HudComponent> getComponents() {
-        return components;
+        return this.components;
     }
 
     public HudComponent getComponent(String key) {
-        for (HudComponent component : components) {
+        for (HudComponent component : this.components) {
             if (component.getKey().equals(key)) {
                 return component;
             }
@@ -36,9 +53,9 @@ public class HudComponents {
         return null;
     }
 
-    public String toSettingsString() {
+    public @NotNull String toSettingsString() {
         StringBuilder builder = new StringBuilder();
-        for (HudComponent component : components) {
+        for (HudComponent component : this.components) {
             builder.append(component.toSettingsString()).append('|');
         }
         return builder.toString();
@@ -57,18 +74,4 @@ public class HudComponents {
             component.fromSettingsString(componentSettings);
         }
     }
-
-    public static final HudComponent HOTBAR = register(new HudComponentHotbar("hotbar", new LayoutAbsolute(0.5f, 1.0f, ComponentAnchor.BOTTOM_CENTER)));
-    public static final HudComponent CROSSHAIR = register(new HudComponentCrosshair("crosshair", new LayoutAbsolute(0.5f, 0.5f, ComponentAnchor.CENTER)));
-    public static final HudComponent HEALTH_BAR = register(new HudComponentHealthBar("health_bar", new LayoutSnap(HOTBAR, ComponentAnchor.TOP_LEFT, ComponentAnchor.BOTTOM_LEFT)));
-//    public static final HudComponent ARMOR_BAR = register(new HudComponentArmorBar("armor_bar", new LayoutSnap(HOTBAR, ComponentAnchor.TOP_RIGHT, ComponentAnchor.BOTTOM_RIGHT)));
-    public static final HudComponent VEHICLE_BAR = register(new HudComponentVehicleHealthBar("vehicle_bar", new LayoutSnap(HOTBAR, ComponentAnchor.TOP_RIGHT, ComponentAnchor.BOTTOM_RIGHT)));
-    public static final HudComponent OXYGEN_BAR = register(new HudComponentOxygenBar("oxygen_bar", new LayoutSnap(HEALTH_BAR, ComponentAnchor.TOP_LEFT, ComponentAnchor.BOTTOM_LEFT)));
-    public static final HudComponent FIRE_BAR = register(new HudComponentFireBar("fire_bar", new LayoutSnap(OXYGEN_BAR, ComponentAnchor.TOP_LEFT, ComponentAnchor.BOTTOM_LEFT)));
-    public static final HudComponent ROTATION_LOCK = register(new HudComponentRotationLock("rotation_lock", new LayoutSnap(CROSSHAIR, ComponentAnchor.CENTER_RIGHT, ComponentAnchor.CENTER_LEFT)));
-    public static final HudComponent SUBTITLES = register(new HudComponentSubtitles("subtitles_box", 100, 50, new LayoutAbsolute(1.0f, 0.75f, ComponentAnchor.BOTTOM_RIGHT)));
-    public static final HudComponent LOG = register(new HudComponentLog("log", new LayoutAbsolute(1.0f, 0.0f, ComponentAnchor.TOP_RIGHT)));
-    public static final HudComponent ARMOR_DURABILITY = register(new HudComponentArmorDurability("armor_durability", new LayoutAbsolute(0.0f, 1.0f, ComponentAnchor.BOTTOM_LEFT)));
-    public static final HudComponent HELD_ITEM_COUNT = register(new HudComponentHeldItemCount("held_item_count", new LayoutSnap(HOTBAR, ComponentAnchor.CENTER_RIGHT, ComponentAnchor.CENTER_LEFT)));
-    public static final HudComponent INFO_OVERLAY = register(new HudComponentInfoOverlay("info_overlay", new LayoutAbsolute(0.0f, 0.0f, ComponentAnchor.TOP_LEFT)));
 }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/layout/LayoutAbsolute.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/layout/LayoutAbsolute.java
index 95b769d4a..0ce40fc8e 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/layout/LayoutAbsolute.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/layout/LayoutAbsolute.java
@@ -1,8 +1,8 @@
 package net.minecraft.client.gui.hud.component.layout;
 
-import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.hud.component.ComponentAnchor;
 import net.minecraft.client.gui.hud.component.HudComponent;
+import net.minecraft.client.option.GameSettings;
 
 public class LayoutAbsolute
     extends Layout {
@@ -17,15 +17,15 @@ public class LayoutAbsolute
     }
 
     public float getXPosition() {
-        return xPosition;
+        return this.xPosition;
     }
 
     public float getYPosition() {
-        return yPosition;
+        return this.yPosition;
     }
 
     public ComponentAnchor getAnchor() {
-        return anchor;
+        return this.anchor;
     }
 
     public void setXPosition(float xPosition) {
@@ -42,31 +42,31 @@ public class LayoutAbsolute
 
     @Override
     public int getComponentX(HudComponent component, int xSizeScreen) {
-        int sp = (int) (mc.gameSettings.screenPadding.value * mc.resolution.getScaledHeightScreenCoords() / 8);
-        return (int) (xPosition * xSizeScreen) - component.getAnchorX(anchor) + sp;
+        int sp = (int) (GameSettings.SCREEN_PADDING.value * mc.resolution.getScaledHeightScreenCoords() / 8);
+        return (int) (this.xPosition * xSizeScreen) - component.getAnchorX(this.anchor) + sp;
     }
 
     @Override
     public int getComponentY(HudComponent component, int ySizeScreen) {
-        int sp = (int) (mc.gameSettings.screenPadding.value * mc.resolution.getScaledHeightScreenCoords() / 8);
-        return (int) (yPosition * ySizeScreen) - component.getAnchorY(anchor) + sp;
+        int sp = (int) (GameSettings.SCREEN_PADDING.value * mc.resolution.getScaledHeightScreenCoords() / 8);
+        return (int) (this.yPosition * ySizeScreen) - component.getAnchorY(this.anchor) + sp;
     }
 
     @Override
     public Layout copy() {
-        return new LayoutAbsolute(xPosition, yPosition, anchor);
+        return new LayoutAbsolute(this.xPosition, this.yPosition, this.anchor);
     }
 
     @Override
     public String toSettingsString() {
-        return xPosition + "," + yPosition + "," + anchor.name();
+        return this.xPosition + "," + this.yPosition + "," + this.anchor.name();
     }
 
     @Override
     public void fromSettingsString(String settings) {
         String[] parts = settings.split(",");
-        xPosition = Float.parseFloat(parts[0]);
-        yPosition = Float.parseFloat(parts[1]);
-        anchor = ComponentAnchor.valueOf(parts[2]);
+        this.xPosition = Float.parseFloat(parts[0]);
+        this.yPosition = Float.parseFloat(parts[1]);
+        this.anchor = ComponentAnchor.valueOf(parts[2]);
     }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/hud/component/layout/LayoutSnap.java b/game/client/src/main/java/net/minecraft/client/gui/hud/component/layout/LayoutSnap.java
index 034cdcbcf..ee443af20 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/hud/component/layout/LayoutSnap.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/hud/component/layout/LayoutSnap.java
@@ -1,9 +1,9 @@
 package net.minecraft.client.gui.hud.component.layout;
 
-import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.hud.component.ComponentAnchor;
 import net.minecraft.client.gui.hud.component.HudComponent;
 import net.minecraft.client.gui.hud.component.HudComponents;
+import net.minecraft.client.option.GameSettings;
 
 public class LayoutSnap
     extends Layout {
@@ -18,15 +18,15 @@ public class LayoutSnap
     }
 
     public HudComponent getParent() {
-        return parent;
+        return this.parent;
     }
 
     public ComponentAnchor getParentAnchor() {
-        return parentAnchor;
+        return this.parentAnchor;
     }
 
     public ComponentAnchor getAnchor() {
-        return anchor;
+        return this.anchor;
     }
 
     public void setParent(HudComponent parent) {
@@ -43,41 +43,41 @@ public class LayoutSnap
 
     @Override
     public int getComponentX(HudComponent component, int xSizeScreen) {
-        if (parent == null) {
-            int sp = (int) (mc.gameSettings.screenPadding.value * mc.resolution.getScaledHeightScreenCoords() / 8);
-            return (int) (xSizeScreen * parentAnchor.xPosition) - component.getAnchorX(anchor) + sp;
+        if (this.parent == null) {
+            int sp = (int) (GameSettings.SCREEN_PADDING.value * mc.resolution.getScaledHeightScreenCoords() / 8);
+            return (int) (xSizeScreen * this.parentAnchor.xPosition) - component.getAnchorX(this.anchor) + sp;
         }
-        return parent.getLayout().getComponentX(parent, xSizeScreen) - component.getAnchorX(anchor) + parent.getAnchorX(parentAnchor);
+        return this.parent.getLayout().getComponentX(this.parent, xSizeScreen) - component.getAnchorX(this.anchor) + this.parent.getAnchorX(this.parentAnchor);
     }
 
     @Override
     public int getComponentY( HudComponent component, int ySizeScreen) {
-        if (parent == null) {
-            int sp = (int) (mc.gameSettings.screenPadding.value * mc.resolution.getScaledHeightScreenCoords() / 8);
-            return (int) (ySizeScreen * parentAnchor.yPosition) - component.getAnchorY(anchor) + sp;
+        if (this.parent == null) {
+            int sp = (int) (GameSettings.SCREEN_PADDING.value * mc.resolution.getScaledHeightScreenCoords() / 8);
+            return (int) (ySizeScreen * this.parentAnchor.yPosition) - component.getAnchorY(this.anchor) + sp;
         }
-        return parent.getLayout().getComponentY(parent, ySizeScreen) - component.getAnchorY(anchor) + parent.getAnchorY(parentAnchor);
+        return this.parent.getLayout().getComponentY(this.parent, ySizeScreen) - component.getAnchorY(this.anchor) + this.parent.getAnchorY(this.parentAnchor);
     }
 
     @Override
     public Layout copy() {
-        return new LayoutSnap(parent, parentAnchor, anchor);
+        return new LayoutSnap(this.parent, this.parentAnchor, this.anchor);
     }
 
     @Override
     public String toSettingsString() {
-        return (parent == null ? "null" : parent.getKey()) + "," + parentAnchor.name() + "," + anchor.name();
+        return (this.parent == null ? "null" : this.parent.getKey()) + "," + this.parentAnchor.name() + "," + this.anchor.name();
     }
 
     @Override
     public void fromSettingsString(String settings) {
         String[] parts = settings.split(",");
         if (parts[0].equals("null")) {
-            parent = null;
+            this.parent = null;
         } else {
-            parent = HudComponents.INSTANCE.getComponent(parts[0]);
+            this.parent = HudComponents.INSTANCE.getComponent(parts[0]);
         }
-        parentAnchor = ComponentAnchor.valueOf(parts[1]);
-        anchor = ComponentAnchor.valueOf(parts[2]);
+        this.parentAnchor = ComponentAnchor.valueOf(parts[1]);
+        this.anchor = ComponentAnchor.valueOf(parts[2]);
     }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/options/OverlayButtonElement.java b/game/client/src/main/java/net/minecraft/client/gui/options/OverlayButtonElement.java
index adcbe7cd4..18db125be 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/options/OverlayButtonElement.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/options/OverlayButtonElement.java
@@ -1,20 +1,16 @@
 package net.minecraft.client.gui.options;
 
 import net.minecraft.client.gui.ButtonElement;
-import net.minecraft.client.option.GameSettings;
 import net.minecraft.core.util.helper.Listener;
 import net.minecraft.core.util.helper.Toggleable;
 import net.minecraft.client.option.Option;
 
 public class OverlayButtonElement<E extends Option<?> & Toggleable> extends ButtonElement implements Listener<ButtonElement>{
-
-	public final GameSettings settings;
 	public final E option;
 	
-	public OverlayButtonElement(GameSettings settings, E option) {
+	public OverlayButtonElement(E option) {
 		super(0, 0, 0, 0, 0, null);
-		
-		this.settings = settings;
+
 		this.option = option;
 		
 		setListener(this);
@@ -24,13 +20,13 @@ public class OverlayButtonElement<E extends Option<?> & Toggleable> extends Butt
 
 	@Override
 	public void listen(ButtonElement e) {
-		option.toggle();
+        this.option.toggle();
 		
 		updateString();
 	}
 	
 	public void updateString() {
-		this.displayString = option.getDisplayString();
+		this.displayString = this.option.getDisplayString();
 	}
 	
 }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/options/ScreenOptions.java b/game/client/src/main/java/net/minecraft/client/gui/options/ScreenOptions.java
index c1694d823..85ed0f78e 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/options/ScreenOptions.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/options/ScreenOptions.java
@@ -11,6 +11,7 @@ import net.minecraft.client.gui.options.data.OptionsPages;
 import net.minecraft.client.input.InputDevice;
 import net.minecraft.client.gui.options.data.OptionsPageRegistry;
 import net.minecraft.client.input.controller.ControllerInput;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.option.KeyBinding;
 import net.minecraft.client.render.Scissor;
 import net.minecraft.client.render.renderer.BlendFactor;
@@ -165,7 +166,7 @@ public class ScreenOptions
             component.onClose();
         }
         super.removed();
-        this.mc.gameSettings.saveOptions();
+        GameSettings.saveOptions();
         this.mc.texturePackList.refreshIfReady();
         reloadIfReady();
     }
@@ -222,6 +223,25 @@ public class ScreenOptions
 
     @Override
     public void render(int mx, int my, float renderPartialTicks) {
+        if (Keyboard.isKeyDown(Keyboard.KEY_LMENU) || Keyboard.isKeyDown(Keyboard.KEY_RMENU)) {
+            int wheel = Mouse.getDWheel();
+
+            int size = GameSettings.GUI_SCALE.size();
+            if (wheel > 0 && GameSettings.GUI_SCALE.value != 0) {
+                GameSettings.GUI_SCALE.value += wheel;
+                if (GameSettings.GUI_SCALE.value > size) GameSettings.GUI_SCALE.value = 0;
+                GameSettings.GUI_SCALE.onUpdate();
+                return;
+            } else if (wheel < 0) {
+                if (GameSettings.GUI_SCALE.value == 0) GameSettings.GUI_SCALE.value += size;
+                GameSettings.GUI_SCALE.value += wheel;
+                if (GameSettings.GUI_SCALE.value <= 0) {
+                    GameSettings.GUI_SCALE.value = 1;
+                }
+                GameSettings.GUI_SCALE.onUpdate();
+                return;
+            }
+        }
         if (pickingKeyBinding != null && pickingKeyBindingComponent != null) {
             mx = -1;
             my = -1;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/options/components/BooleanOptionComponent.java b/game/client/src/main/java/net/minecraft/client/gui/options/components/BooleanOptionComponent.java
index 85eeb0735..31b9a0519 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/options/components/BooleanOptionComponent.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/options/components/BooleanOptionComponent.java
@@ -2,7 +2,6 @@ package net.minecraft.client.gui.options.components;
 
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.SwitchElement;
-import net.minecraft.client.option.Option;
 import net.minecraft.client.option.OptionBoolean;
 import net.minecraft.client.render.window.CursorShape;
 import org.jetbrains.annotations.Nullable;
@@ -19,10 +18,10 @@ public class BooleanOptionComponent
 
     public BooleanOptionComponent(OptionBoolean option, @Nullable String tooltipTranslationKey)
     {
-        super("options." + option.name, null);
+        super("options." + option.id, null);
 
         this.option = option;
-        this.option.addCallback(__ -> onChange());
+        this.option.addOnChangeCallback((mc, __) -> onChange());
         this.button = new SwitchElement(0, 0, 0, 150, 20, this.option.value, "", "");
         this.button.setOn(this.option.value);
         this.button.displayString = this.option.getDisplayStringValue();
@@ -30,8 +29,8 @@ public class BooleanOptionComponent
 
     @Override
     public void resetValue() {
-        option.set(option.getDefaultValue());
-        option.onUpdate();
+        this.option.set(this.option.getDefaultValue());
+        this.option.onUpdate();
         onChange();
     }
 
@@ -42,7 +41,7 @@ public class BooleanOptionComponent
 
     @Override
     public boolean isDefault() {
-        return option.value.equals(option.getDefaultValue());
+        return this.option.value.equals(this.option.getDefaultValue());
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/gui/options/components/DifficultyOptionComponent.java b/game/client/src/main/java/net/minecraft/client/gui/options/components/DifficultyOptionComponent.java
index dc0a9653e..6afd549ec 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/options/components/DifficultyOptionComponent.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/options/components/DifficultyOptionComponent.java
@@ -8,7 +8,6 @@ import net.minecraft.client.option.OptionEnum;
 import net.minecraft.client.render.window.CursorShape;
 import net.minecraft.core.enums.Difficulty;
 import net.minecraft.core.lang.I18n;
-import net.minecraft.core.net.command.TextFormatting;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.Objects;
@@ -24,9 +23,9 @@ public class DifficultyOptionComponent extends ButtonComponent {
     }
 
     public DifficultyOptionComponent(OptionEnum<Difficulty> difficultyOption, @Nullable String tooltipTranslationKey) {
-        super("options." + difficultyOption.name, tooltipTranslationKey);
+        super("options." + difficultyOption.id, tooltipTranslationKey);
         option = difficultyOption;
-        option.addCallback(__ -> onChanged());
+        option.addOnChangeCallback((mc, __) -> onChanged());
         this.slider = new IntegerSliderElement(0, 0, 0, 150 - 22, 20, option);
         this.lockButton = new ButtonElement(1, 150 - 20, 0, 20, 20, "");
         this.lockButton.setTextures("minecraft:gui/widgets/button/button_locked", "minecraft:gui/widgets/button/button_locked_highlighted", "minecraft:gui/widgets/button/button_locked_disabled");
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 085adda56..1260bc80b 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
@@ -32,10 +32,10 @@ public class FloatOptionComponent
 
     public FloatOptionComponent(OptionFloat option, float minValue, float maxValue, @Nullable String tooltipTranslationKey)
     {
-        super("options." + option.name, tooltipTranslationKey);
+        super("options." + option.id, tooltipTranslationKey);
 
         this.option = option;
-        this.option.addCallback(__ -> onChanged());
+        this.option.addOnChangeCallback((mc, __) -> onChanged());
         this.slider = new SliderElement(0, 0, 0, 150, 20, this.option.getDisplayStringValue(), this.option.value);
 
         this.minValue = minValue;
diff --git a/game/client/src/main/java/net/minecraft/client/gui/options/components/FramerateOptionComponent.java b/game/client/src/main/java/net/minecraft/client/gui/options/components/FramerateOptionComponent.java
index ea8bd9dd1..3f4001b2f 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/options/components/FramerateOptionComponent.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/options/components/FramerateOptionComponent.java
@@ -1,6 +1,7 @@
 package net.minecraft.client.gui.options.components;
 
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.option.OptionRange;
 import net.minecraft.client.render.window.CursorShape;
 import net.minecraft.client.render.window.GameWindowGLFW;
@@ -18,14 +19,14 @@ public class FramerateOptionComponent extends ToggleableOptionComponent<Integer>
     @Override
     protected void renderButton(int x, int y, int relativeButtonX, int relativeButtonY, int buttonWidth, int buttonHeight, int relativeMouseX, int relativeMouseY)
     {
-        if (mc.gameSettings.enableVsync.value && mc.gameWindow instanceof GameWindowGLFW) {
-        	slider.sliderValue = mc.gameWindow.getFrequency();
+        if (GameSettings.ENABLE_VSYNC.value && mc.gameWindow instanceof GameWindowGLFW) {
+            this.slider.sliderValue = mc.gameWindow.getFrequency();
             onChanged();
-            slider.enabled = false;
+            this.slider.enabled = false;
         }else {
-            slider.sliderValue = option.value;
+            this.slider.sliderValue = this.option.value;
             onChanged();
-            slider.enabled = true;
+            this.slider.enabled = true;
         }
 
         super.renderButton(x, y, relativeButtonX, relativeButtonY, buttonWidth, buttonHeight, relativeMouseX, relativeMouseY);
@@ -43,10 +44,10 @@ public class FramerateOptionComponent extends ToggleableOptionComponent<Integer>
     }
     @Override
     public void init(Minecraft mc){
-        slider.sliderValue = option.getValueIndex();
-        if (mc.gameSettings.enableVsync.value && mc.gameWindow instanceof GameWindowGLFW) {
-            slider.sliderValue = mc.gameWindow.getFrequency();
-            slider.enabled = false;
+        this.slider.sliderValue = this.option.getValueIndex();
+        if (GameSettings.ENABLE_VSYNC.value && mc.gameWindow instanceof GameWindowGLFW) {
+            this.slider.sliderValue = mc.gameWindow.getFrequency();
+            this.slider.enabled = false;
         }
         onChanged();
     }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/options/components/IntegerOptionComponent.java b/game/client/src/main/java/net/minecraft/client/gui/options/components/IntegerOptionComponent.java
index 250f06003..1f6f29b22 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/options/components/IntegerOptionComponent.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/options/components/IntegerOptionComponent.java
@@ -19,10 +19,10 @@ public class IntegerOptionComponent
 
     public IntegerOptionComponent(OptionInteger option, @Nullable String tooltipTranslationKey)
     {
-        super("options." + option.name, tooltipTranslationKey);
+        super("options." + option.id, tooltipTranslationKey);
 
         this.option = option;
-        this.option.addCallback(__ -> onChanged());
+        this.option.addOnChangeCallback((mc, __) -> onChanged());
         this.button = new ButtonElement(0, 0, 0, 150, 20, this.option.getDisplayString());
     }
 
diff --git a/game/client/src/main/java/net/minecraft/client/gui/options/components/LanguagePackListComponent.java b/game/client/src/main/java/net/minecraft/client/gui/options/components/LanguagePackListComponent.java
index ae1424cce..d42284651 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/options/components/LanguagePackListComponent.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/options/components/LanguagePackListComponent.java
@@ -3,6 +3,7 @@ package net.minecraft.client.gui.options.components;
 import com.mojang.logging.LogUtils;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.options.ScreenOptions;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.Shaders;
 import net.minecraft.client.render.tessellator.TessellatorGeneral;
@@ -25,8 +26,6 @@ public class LanguagePackListComponent
     private static final Logger LOGGER = LogUtils.getLogger();
     private static final int BUTTON_HEIGHT = 32;
 
-    private List<Language> languages = null;
-
     private final List<LanguagePackComponent> buttons = new ArrayList<>();
 
     public LanguagePackListComponent() {
@@ -43,9 +42,9 @@ public class LanguagePackListComponent
         this.buttons.clear();
 
         try {
-            this.languages = LanguageSeeker.getAvailableLanguages();
-            for (int i = 0; i < this.languages.size(); i++) {
-                Language language = this.languages.get(i);
+            List<Language> languages = LanguageSeeker.getAvailableLanguages();
+            for (int i = 0; i < languages.size(); i++) {
+                Language language = languages.get(i);
                 this.buttons.add(new LanguagePackComponent(i, language));
             }
         } catch (IOException e) {
@@ -72,7 +71,7 @@ public class LanguagePackListComponent
             LanguagePackComponent button = this.buttons.get(i);
             if (relativeMouseX >= 0 && relativeMouseX <= width && relativeMouseY >= 3 + i * (BUTTON_HEIGHT + 3) && relativeMouseY <= 3 + i * (BUTTON_HEIGHT + 3) + BUTTON_HEIGHT) {
                 String lang = button.languagePack.getId();
-                mc.gameSettings.language.set(lang);
+                GameSettings.LANGUAGE.set(lang);
                 I18n.getInstance().reload(lang);
                 mc.currentScreen.init();
             }
@@ -108,7 +107,7 @@ public class LanguagePackListComponent
         }
 
         public void render(int x, int y, int width, int mouseX, int mouseY) {
-            if (this.mc.gameSettings.language.value.equals(this.languagePack.getId())) {
+            if (GameSettings.LANGUAGE.value.equals(this.languagePack.getId())) {
                 // Draw background
                 GLRenderer.pushFrame();
                 GLRenderer.setShader(Shaders.COLOR);
diff --git a/game/client/src/main/java/net/minecraft/client/gui/options/components/ToggleableOptionComponent.java b/game/client/src/main/java/net/minecraft/client/gui/options/components/ToggleableOptionComponent.java
index 130315d36..0a5987247 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/options/components/ToggleableOptionComponent.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/options/components/ToggleableOptionComponent.java
@@ -4,6 +4,7 @@ import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.IntegerSliderElement;
 import net.minecraft.client.option.OptionToggleable;
 import net.minecraft.client.render.window.CursorShape;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 public class ToggleableOptionComponent<E>
@@ -11,6 +12,7 @@ public class ToggleableOptionComponent<E>
 {
     protected final OptionToggleable<E> option;
     protected final IntegerSliderElement slider;
+    protected boolean applyOnRelease = false;
 
     public ToggleableOptionComponent(OptionToggleable<E> option)
     {
@@ -19,13 +21,18 @@ public class ToggleableOptionComponent<E>
 
     public ToggleableOptionComponent(OptionToggleable<E> option, @Nullable String tooltipTranslationKey)
     {
-        super("options." + option.name, tooltipTranslationKey);
+        super("options." + option.id, tooltipTranslationKey);
 
         this.option = option;
-        this.option.addCallback(__ -> onChanged());
+        this.option.addOnChangeCallback((mc, __) -> onChanged());
         this.slider = new IntegerSliderElement(0, 0, 0, 150, 20, option);
     }
 
+    public @NotNull ToggleableOptionComponent<E> applyOnRelease() {
+        this.applyOnRelease = true;
+        return this;
+    }
+
     @Override
     public void resetValue() {
         option.set(option.getDefaultValue());
@@ -38,13 +45,17 @@ public class ToggleableOptionComponent<E>
     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);
         onChanged();
-        this.option.onUpdate();
+        if (!applyOnRelease) {
+            this.option.onUpdate();
+        }
     }
 
     @Override
     protected void buttonDragged(int x, int y, int width, int height, int relativeMouseX, int relativeMouseY) {
         onChanged();
-        this.option.onUpdate();
+        if (!applyOnRelease) {
+            this.option.onUpdate();
+        }
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/gui/options/data/OptionsPageDebug.java b/game/client/src/main/java/net/minecraft/client/gui/options/data/OptionsPageDebug.java
index e0ed7502c..c277e18df 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/options/data/OptionsPageDebug.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/options/data/OptionsPageDebug.java
@@ -1,6 +1,7 @@
 package net.minecraft.client.gui.options.data;
 
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.core.item.ItemStack;
 import org.jetbrains.annotations.NotNull;
 
@@ -13,6 +14,6 @@ public class OptionsPageDebug
 
     @Override
     public boolean isVisible(@NotNull Minecraft mc) {
-        return mc.gameSettings.developerMode.value;
+        return GameSettings.DEVELOPER_MODE.value;
     }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java b/game/client/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java
index c523ac235..5299c2583 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/options/data/OptionsPages.java
@@ -13,14 +13,26 @@ import net.minecraft.client.gui.achievements.ScreenAchievements;
 import net.minecraft.client.gui.modelviewer.ScreenModelViewer;
 import net.minecraft.client.gui.nbteditor.ScreenNBTEditor;
 import net.minecraft.client.gui.options.ScreenOptions;
-import net.minecraft.client.gui.options.components.*;
+import net.minecraft.client.gui.options.components.AvailableTexturePackListComponent;
+import net.minecraft.client.gui.options.components.BooleanOptionComponent;
+import net.minecraft.client.gui.options.components.DifficultyOptionComponent;
+import net.minecraft.client.gui.options.components.FloatOptionComponent;
+import net.minecraft.client.gui.options.components.FramerateOptionComponent;
+import net.minecraft.client.gui.options.components.KeyBindingComponent;
+import net.minecraft.client.gui.options.components.LanguagePackListComponent;
+import net.minecraft.client.gui.options.components.OptionsCategory;
+import net.minecraft.client.gui.options.components.SearchFieldComponent;
+import net.minecraft.client.gui.options.components.SelectedTexturePackListComponent;
+import net.minecraft.client.gui.options.components.ShortcutComponent;
+import net.minecraft.client.gui.options.components.ToggleableOptionComponent;
+import net.minecraft.client.gui.options.components.TooltipPickerComponent;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.player.controller.PlayerControllerSP;
 import net.minecraft.client.sound.SoundEngine;
 import net.minecraft.client.util.helper.FileOpener;
 import net.minecraft.client.util.helper.JavaProcess;
 import net.minecraft.client.world.WorldClient;
 import net.minecraft.core.Global;
-import net.minecraft.core.UnexpectedThrowable;
 import net.minecraft.core.achievement.stat.Stat;
 import net.minecraft.core.achievement.stat.StatList;
 import net.minecraft.core.block.Blocks;
@@ -60,35 +72,35 @@ public abstract class OptionsPages {
 
         GENERAL = register(new OptionsPage("gui.options.page.general.title", new ItemStack(Blocks.GRASS_RETRO))
             .withComponent(new OptionsCategory("gui.options.page.general.category.gameplay")
-                .withComponent(new FloatOptionComponent(mc.gameSettings.FoV))
-                .withComponent(new DifficultyOptionComponent(mc.gameSettings.difficulty))
-                .withComponent(new ToggleableOptionComponent<>(mc.gameSettings.placementMode))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.autoHit))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.easyBridge))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.viewBobbing))
+                .withComponent(new FloatOptionComponent(GameSettings.FOV))
+                .withComponent(new DifficultyOptionComponent(GameSettings.DIFFICULTY))
+                .withComponent(new ToggleableOptionComponent<>(GameSettings.PLACEMENT_MODE))
+                .withComponent(new BooleanOptionComponent(GameSettings.AUTO_HIT))
+                .withComponent(new BooleanOptionComponent(GameSettings.EASY_BRIDGE))
+                .withComponent(new BooleanOptionComponent(GameSettings.VIEW_BOBBING))
             )
             .withComponent(new OptionsCategory("gui.options.page.general.category.user_interface")
                 .withComponent(new ShortcutComponent("gui.options.page.general.button.edit_hud", () -> mc.displayScreen(new ScreenHudDesigner(mc.currentScreen))))
-                .withComponent(new IntegerOptionComponent(mc.gameSettings.guiScale))
-                .withComponent(new FloatOptionComponent(mc.gameSettings.screenPadding))
-                .withComponent(new TooltipPickerComponent(mc.gameSettings.tooltipStyle))
-                .withComponent(new ToggleableOptionComponent<>(mc.gameSettings.font))
-                .withComponent(new ToggleableOptionComponent<>(mc.gameSettings.chatVisibility))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.fpsInOverlay))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.versionInOverlay))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.foodHealthRegenOverlay))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.armorDurabilityOverlay))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.heldItemCountOverlay))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.heldItemTooltips))
-                .withComponent(new ToggleableOptionComponent<>(mc.gameSettings.itemDescriptions))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.hideUndiscoveredItems))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.dynamicCursor))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.musicToasts))
+                .withComponent(new ToggleableOptionComponent<>(GameSettings.GUI_SCALE).applyOnRelease())
+                .withComponent(new FloatOptionComponent(GameSettings.SCREEN_PADDING))
+                .withComponent(new TooltipPickerComponent(GameSettings.TOOLTIP_STYLE))
+                .withComponent(new ToggleableOptionComponent<>(GameSettings.FONT))
+                .withComponent(new ToggleableOptionComponent<>(GameSettings.chatVisibility))
+                .withComponent(new BooleanOptionComponent(GameSettings.FPS_IN_OVERLAY))
+                .withComponent(new BooleanOptionComponent(GameSettings.VERSION_IN_OVERLAY))
+                .withComponent(new BooleanOptionComponent(GameSettings.FOOD_HEALTH_REGEN_OVERLAY))
+                .withComponent(new BooleanOptionComponent(GameSettings.ARMOR_DURABILITY_OVERLAY))
+                .withComponent(new BooleanOptionComponent(GameSettings.HELD_ITEM_COUNT_OVERLAY))
+                .withComponent(new BooleanOptionComponent(GameSettings.HELD_ITEM_TOOLTIPS))
+                .withComponent(new ToggleableOptionComponent<>(GameSettings.ITEM_DESCRIPTIONS))
+                .withComponent(new BooleanOptionComponent(GameSettings.HIDE_UNDISCOVERED_ITEMS))
+                .withComponent(new BooleanOptionComponent(GameSettings.DYNAMIC_CURSOR))
+                .withComponent(new BooleanOptionComponent(GameSettings.MUSIC_TOASTS))
             )
             .withComponent(new OptionsCategory("gui.options.page.general.category.miscellaneous")
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.discordRichPresence))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.enableItemClumping))
-                .withComponent(new FloatOptionComponent(mc.gameSettings.autosaveTimer))
+                .withComponent(new BooleanOptionComponent(GameSettings.DISCORD_RICH_PRESENCE))
+                .withComponent(new BooleanOptionComponent(GameSettings.ENABLE_ITEM_CLUMPING))
+                .withComponent(new FloatOptionComponent(GameSettings.AUTOSAVE_TIMER))
             )
             .withComponent(new ShortcutComponent("gui.options.page.general.button.open_worlds_folder", () -> FileOpener.open(new File(mc.getMinecraftDir(), "saves"))))
             .withComponent(new ShortcutComponent("gui.options.page.general.button.open_screenshots_folder", () -> {
@@ -101,193 +113,202 @@ public abstract class OptionsPages {
 
         PLAYER = register(new OptionsPage("gui.options.page.player.title", new ItemStack(Items.STATUE_STONE))
             .withComponent(new OptionsCategory("gui.options.page.player.category.player")
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.playerLeftHanded))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.playerCape))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.playerHat))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.playerJacket))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.playerSleeveLeft))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.playerSleeveRight))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.playerPantLeft))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.playerPantRight))
-                .withComponent(new ToggleableOptionComponent<>(mc.gameSettings.playerHurtSound))
+                .withComponent(new BooleanOptionComponent(GameSettings.PLAYER_LEFT_HANDED))
+                .withComponent(new BooleanOptionComponent(GameSettings.PLAYER_CAPE))
+                .withComponent(new BooleanOptionComponent(GameSettings.PLAYER_HAT))
+                .withComponent(new BooleanOptionComponent(GameSettings.PLAYER_JACKET))
+                .withComponent(new BooleanOptionComponent(GameSettings.PLAYER_SLEEVE_LEFT))
+                .withComponent(new BooleanOptionComponent(GameSettings.PLAYER_SLEEVE_RIGHT))
+                .withComponent(new BooleanOptionComponent(GameSettings.PLAYER_PANT_LEFT))
+                .withComponent(new BooleanOptionComponent(GameSettings.PLAYER_PANT_RIGHT))
+                .withComponent(new ToggleableOptionComponent<>(GameSettings.PLAYER_HURT_SOUND))
             )
         );
 
         AUDIO = register(new OptionsPage("gui.options.page.audio.title", new ItemStack(Items.RECORD_CAT))
             .withComponent(new OptionsCategory("gui.options.page.audio.category.audio")
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.subtitles))
-                .withComponent(new ToggleableOptionComponent<>(mc.gameSettings.musicFrequency))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.muteOnLostFocus))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.playTitleScreenMusic))
-                .withComponent(new FloatOptionComponent(mc.gameSettings.masterVolume))
-                .withComponent(new FloatOptionComponent(mc.gameSettings.musicVolume))
-                .withComponent(new FloatOptionComponent(mc.gameSettings.worldSoundsVolume))
-                .withComponent(new FloatOptionComponent(mc.gameSettings.weatherSoundsVolume))
-                .withComponent(new FloatOptionComponent(mc.gameSettings.entitySoundsVolume))
-                .withComponent(new FloatOptionComponent(mc.gameSettings.caveSoundsVolume))
-                .withComponent(new FloatOptionComponent(mc.gameSettings.guiSoundsVolume))
+                .withComponent(new BooleanOptionComponent(GameSettings.SUBTITLES))
+                .withComponent(new ToggleableOptionComponent<>(GameSettings.MUSIC_FREQUENCY))
+                .withComponent(new BooleanOptionComponent(GameSettings.MUTE_ON_LOST_FOCUS))
+                .withComponent(new BooleanOptionComponent(GameSettings.PLAY_TITLE_SCREEN_MUSIC))
+                .withComponent(new FloatOptionComponent(GameSettings.MASTER_VOLUME))
+                .withComponent(new FloatOptionComponent(GameSettings.MUSIC_VOLUME))
+                .withComponent(new FloatOptionComponent(GameSettings.WORLD_SOUNDS_VOLUME))
+                .withComponent(new FloatOptionComponent(GameSettings.WEATHER_SOUNDS_VOLUME))
+                .withComponent(new FloatOptionComponent(GameSettings.ENTITY_SOUNDS_VOLUME))
+                .withComponent(new FloatOptionComponent(GameSettings.CAVE_SOUNDS_VOLUME))
+                .withComponent(new FloatOptionComponent(GameSettings.GUI_SOUNDS_VOLUME))
             )
         );
 
         VIDEO = register(new OptionsPage("gui.options.page.video.title", new ItemStack(Items.FLAG))
                 .withComponent(new OptionsCategory("gui.options.page.video.category.graphics")
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.fullscreen))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.borderlessFullscreen))
-                    .withComponent(new ToggleableOptionComponent<>(mc.gameSettings.renderScale))
-                    .withComponent(new ToggleableOptionComponent<>(mc.gameSettings.fancyGraphics))
-                    .withComponent(new ToggleableOptionComponent<>(mc.gameSettings.renderDistance))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.ambientOcclusion))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.connectedGlass))
-                    .withComponent(new ToggleableOptionComponent<>(mc.gameSettings.mipmapLevels))
-                    .withComponent(new ToggleableOptionComponent<>(mc.gameSettings.mipmapType))
-                    .withComponent(new ToggleableOptionComponent<>(mc.gameSettings.colorblindnessFix))
+                    .withComponent(new BooleanOptionComponent(GameSettings.FULLSCREEN))
+                    .withComponent(new BooleanOptionComponent(GameSettings.BORDERLESS_FULLSCREEN))
+                    .withComponent(new ToggleableOptionComponent<>(GameSettings.RENDER_SCALE))
+                    .withComponent(new ToggleableOptionComponent<>(GameSettings.RENDER_DISTANCE))
+                    .withComponent(new BooleanOptionComponent(GameSettings.AMBIENT_OCCLUSION))
+                    .withComponent(new BooleanOptionComponent(GameSettings.CONNECTED_GLASS))
+                    .withComponent(new ToggleableOptionComponent<>(GameSettings.MIPMAP_LEVELS).applyOnRelease())
+                    .withComponent(new ToggleableOptionComponent<>(GameSettings.MIPMAP_TYPE).applyOnRelease())
+                    .withComponent(new ToggleableOptionComponent<>(GameSettings.COLORBLINDNESS_FIX))
                 )
                 .withComponent(new OptionsCategory("gui.options.page.video.category.performance")
-                        .withComponent(new BooleanOptionComponent(mc.gameSettings.enableVsync))
-                        .withComponent(new FramerateOptionComponent(mc.gameSettings.customFpsLimit))
-//                .withComponent(new BooleanOptionComponent(mc.gameSettings.advancedOpenGL))
+                        .withComponent(new BooleanOptionComponent(GameSettings.ENABLE_VSYNC))
+                        .withComponent(new FramerateOptionComponent(GameSettings.CUSTOM_FPS_LIMIT))
+//                .withComponent(new BooleanOptionComponent(GameSettings.advancedOpenGL))
                 )
                 .withComponent(new OptionsCategory("gui.options.page.video.category.post_processing")
-                    .withComponent(new FloatOptionComponent(mc.gameSettings.gamma))
-                    .withComponent(new FloatOptionComponent(mc.gameSettings.colorCorrection))
-                    .withComponent(new FloatOptionComponent(mc.gameSettings.fxaa))
-                    .withComponent(new ToggleableOptionComponent<>(mc.gameSettings.bloom))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.heatHaze))
+                    .withComponent(new FloatOptionComponent(GameSettings.GAMMA))
+                    .withComponent(new FloatOptionComponent(GameSettings.COLOR_CORRECTION))
+                    .withComponent(new FloatOptionComponent(GameSettings.FXAA))
+                    .withComponent(new ToggleableOptionComponent<>(GameSettings.BLOOM))
+                    .withComponent(new BooleanOptionComponent(GameSettings.HEAT_HAZE))
                 )
                 .withComponent(new OptionsCategory("gui.options.page.video.category.visuals")
-                    .withComponent(new ToggleableOptionComponent<>(mc.gameSettings.lightmapStyle))
-                    .withComponent(new FloatOptionComponent(mc.gameSettings.brightness))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.fovModification))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.screenMotionEffects))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.fog))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.biomeWater))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.treeShadows))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.vignette))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.items3D))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.clouds))
-                    .withComponent(new FloatOptionComponent(mc.gameSettings.cloudHeight, -0.5f, 1f))
-                    .withComponent(new FloatOptionComponent(mc.gameSettings.entityRenderDistance, 0.1f, 3f))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.aurora))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.slimeParticles))
-                    .withComponent(new FloatOptionComponent(mc.gameSettings.blockOutlineWidth))
+                    .withComponent(new ToggleableOptionComponent<>(GameSettings.LIGHTMAP_STYLE))
+                    .withComponent(new FloatOptionComponent(GameSettings.BRIGHTNESS))
+                    .withComponent(new BooleanOptionComponent(GameSettings.FOV_MODIFICATION))
+                    .withComponent(new BooleanOptionComponent(GameSettings.SCREEN_MOTION_EFFECTS))
+                    .withComponent(new BooleanOptionComponent(GameSettings.FOG))
+                    .withComponent(new BooleanOptionComponent(GameSettings.BIOME_WATER))
+                    .withComponent(new FloatOptionComponent(GameSettings.ENTITY_RENDER_DISTANCE, 0.1f, 3f))
+                    .withComponent(new BooleanOptionComponent(GameSettings.ENTITY_SHADOWS))
+                    .withComponent(new ToggleableOptionComponent<>(GameSettings.TEXT_OUTLINE_QUALITY))
+                    .withComponent(new BooleanOptionComponent(GameSettings.CLOUDS))
+                    .withComponent(new ToggleableOptionComponent<>(GameSettings.CLOUD_QUALITY))
+                    .withComponent(new FloatOptionComponent(GameSettings.CLOUD_HEIGHT, -0.5f, 1f))
+                    .withComponent(new ToggleableOptionComponent<>(GameSettings.LEAVES_QUALITY).applyOnRelease())
+                    .withComponent(new ToggleableOptionComponent<>(GameSettings.PARTICLES_QUALITY))
+                    .withComponent(new ToggleableOptionComponent<>(GameSettings.PARTICLES_CAP))
+                    .withComponent(new FloatOptionComponent(GameSettings.PARTICLE_RENDER_DISTANCE, 0.1f, 3f))
+                    .withComponent(new BooleanOptionComponent(GameSettings.TREE_SHADOWS))
+                    .withComponent(new BooleanOptionComponent(GameSettings.VIGNETTE))
+                    .withComponent(new BooleanOptionComponent(GameSettings.ITEMS_3D))
+                    .withComponent(new BooleanOptionComponent(GameSettings.AURORA))
+                    .withComponent(new BooleanOptionComponent(GameSettings.SLIME_PARTICLES))
+                    .withComponent(new FloatOptionComponent(GameSettings.BLOCK_OUTLINE_WIDTH))
+                    .withComponent(new BooleanOptionComponent(GameSettings.TRANSPARENCY_DEPTH_CHECK))
+                    .withComponent(new BooleanOptionComponent(GameSettings.FRUSTUM_CULLING))
+                    .withComponent(new ToggleableOptionComponent<>(GameSettings.CHUNK_REBUILDS_PER_FRAME))
                 )
         );
 
         CONTROLS = register(new OptionsPage("gui.options.page.controls.title", new ItemStack(Items.BOAT))
             .withComponent(new OptionsCategory("gui.options.page.controls.category.mouse")
-                .withComponent(new FloatOptionComponent(mc.gameSettings.mouseSensitivity))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.invertMouse))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.rawMouseInput))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.enableItemDragging))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.smoothCamera))
-                .withComponent(new FloatOptionComponent(mc.gameSettings.flightSmoothness))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.turnWithVehicle))
+                .withComponent(new FloatOptionComponent(GameSettings.MOUSE_SENSITIVITY))
+                .withComponent(new BooleanOptionComponent(GameSettings.INVERT_MOUSE))
+                .withComponent(new BooleanOptionComponent(GameSettings.RAW_MOUSE_INPUT))
+                .withComponent(new BooleanOptionComponent(GameSettings.ENABLE_ITEM_DRAGGING))
+                .withComponent(new BooleanOptionComponent(GameSettings.SMOOTH_CAMERA))
+                .withComponent(new FloatOptionComponent(GameSettings.FLIGHT_SMOOTHNESS))
+                .withComponent(new BooleanOptionComponent(GameSettings.TURN_WITH_VEHICLE))
             )
             .withComponent(new OptionsCategory("gui.options.page.controls.category.keyboard")
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.sneakToggle))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.swapCraftingButtons))
+                .withComponent(new BooleanOptionComponent(GameSettings.SNEAK_TOGGLE))
+                .withComponent(new BooleanOptionComponent(GameSettings.SWAP_CRAFTING_BUTTONS))
             )
             .withComponent(new OptionsCategory("gui.options.page.controls.category.controller")
                 .withComponent(new ShortcutComponent("gui.options.page.controls.button.controller_setup", () -> mc.displayScreen(new ScreenControllerSetup(mc.currentScreen))))
-                .withComponent(new FloatOptionComponent(mc.gameSettings.controllerSensitivity))
-                .withComponent(new FloatOptionComponent(mc.gameSettings.controllerMenuSensitivity))
-                .withComponent(new FloatOptionComponent(mc.gameSettings.controllerDeadzoneLeft))
-                .withComponent(new FloatOptionComponent(mc.gameSettings.controllerDeadzoneRight))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.controllerSwapShoulderButtons))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.controllerSwapAB))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.controllerSwapXY))
+                .withComponent(new FloatOptionComponent(GameSettings.CONTROLLER_SENSITIVITY))
+                .withComponent(new FloatOptionComponent(GameSettings.CONTROLLER_MENU_SENSITIVITY))
+                .withComponent(new FloatOptionComponent(GameSettings.CONTROLLER_DEADZONE_LEFT))
+                .withComponent(new FloatOptionComponent(GameSettings.CONTROLLER_DEADZONE_RIGHT))
+                .withComponent(new BooleanOptionComponent(GameSettings.CONTROLLER_SWAP_SHOULDER_BUTTONS))
+                .withComponent(new BooleanOptionComponent(GameSettings.CONTROLLER_SWAP_AB))
+                .withComponent(new BooleanOptionComponent(GameSettings.CONTROLLER_SWAP_XY))
             )
             .withComponent(new OptionsCategory("gui.options.page.controls.category.interactions")
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyAttack))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyInteract))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyPickBlock))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_ATTACK))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_INTERACT))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_PICK_BLOCK))
             )
             .withComponent(new OptionsCategory("gui.options.page.controls.category.movement")
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyForward))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyBack))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyLeft))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyRight))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyJump))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keySneak))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyFly))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyAutoWalk))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyEasyBridge))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keySprint))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_FORWARD))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_BACK))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_LEFT))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_RIGHT))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_JUMP))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_SNEAK))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_FLY))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_AUTO_WALK))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_EASY_BRIDGE))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_SPRINT))
             )
             .withComponent(new OptionsCategory("gui.options.page.controls.category.user_interface")
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.forceOnscreenKeyboard))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyInventory))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyChat))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyCommand))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyGuidebook))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyShowRecipe))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyShowUsage))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyDescription))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyOpenAchievements))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyOpenStatistics))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyPlayerList))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyHideGui))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyToggleDebug))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyToggleOverlay))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keySortInventory))
+                .withComponent(new BooleanOptionComponent(GameSettings.FORCE_ONSCREEN_KEYBOARD))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_INVENTORY))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_CHAT))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_COMMAND))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_GUIDEBOOK))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_SHOW_RECIPE))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_SHOW_USAGE))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_DESCRIPTION))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_OPEN_ACHIEVEMENTS))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_OPEN_STATISTICS))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_PLAYER_LIST))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_HIDE_GUI))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_TOGGLE_DEBUG))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_TOGGLE_OVERLAY))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_SORT_INVENTORY))
             )
             .withComponent(new OptionsCategory("gui.options.page.controls.category.hotbar")
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyHotBarLeft))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyHotBarRight))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyHotBarSwitch))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyDrop))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyHotBarSlot1))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyHotBarSlot2))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyHotBarSlot3))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyHotBarSlot4))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyHotBarSlot5))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyHotBarSlot6))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyHotBarSlot7))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyHotBarSlot8))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyHotBarSlot9))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_HOT_BAR_LEFT))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_HOT_BAR_RIGHT))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_HOT_BAR_SWITCH))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_DROP))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_HOT_BAR_SLOT_1))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_HOT_BAR_SLOT_2))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_HOT_BAR_SLOT_3))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_HOT_BAR_SLOT_4))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_HOT_BAR_SLOT_5))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_HOT_BAR_SLOT_6))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_HOT_BAR_SLOT_7))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_HOT_BAR_SLOT_8))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_HOT_BAR_SLOT_9))
             )
             .withComponent(new OptionsCategory("gui.options.page.controls.category.view")
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyLookLeft))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyLookRight))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyLookUp))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyLookDown))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyCenterView))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyZoom))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyCinematicCamera))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keySwitchPerspective))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyPhotoMode))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_LOOK_LEFT))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_LOOK_RIGHT))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_LOOK_UP))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_LOOK_DOWN))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_CENTER_VIEW))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_ZOOM))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_CINEMATIC_CAMERA))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_SWITCH_PERSPECTIVE))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_PHOTO_MODE))
             )
             .withComponent(new OptionsCategory("gui.options.page.controls.category.miscellaneous")
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyToggleFog))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyToggleGamma))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyLockRotation))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyScreenshot))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyShowConsole))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyFullScreen))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_TOGGLE_FOG))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_TOGGLE_GAMMA))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_LOCK_ROTATION))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_SCREENSHOT))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_SHOW_CONSOLE))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_FULL_SCREEN))
             )
         );
 
         ACCESSIBILITY = register(new OptionsPage("gui.options.page.accessibility.title", new ItemStack(Items.WAND_MONSTER_SPAWNER))
             .withComponent(new OptionsCategory("gui.options.page.accessibility.category.accessibility")
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.subtitles))
-                .withComponent(new IntegerOptionComponent(mc.gameSettings.guiScale))
-                .withComponent(new FloatOptionComponent(mc.gameSettings.screenPadding))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.viewBobbing))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.fovModification))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.screenMotionEffects))
-                .withComponent(new ToggleableOptionComponent<>(mc.gameSettings.colorblindnessFix))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.turnWithVehicle))
+                .withComponent(new BooleanOptionComponent(GameSettings.SUBTITLES))
+                .withComponent(new ToggleableOptionComponent<>(GameSettings.GUI_SCALE).applyOnRelease())
+                .withComponent(new FloatOptionComponent(GameSettings.SCREEN_PADDING))
+                .withComponent(new BooleanOptionComponent(GameSettings.VIEW_BOBBING))
+                .withComponent(new BooleanOptionComponent(GameSettings.FOV_MODIFICATION))
+                .withComponent(new BooleanOptionComponent(GameSettings.SCREEN_MOTION_EFFECTS))
+                .withComponent(new ToggleableOptionComponent<>(GameSettings.COLORBLINDNESS_FIX))
+                .withComponent(new BooleanOptionComponent(GameSettings.TURN_WITH_VEHICLE))
             )
         );
 
         ASSET_PACKS = register(new OptionsPage("gui.options.page.asset_packs.title", new ItemStack(Items.PAINTING))
             .withComponent(new ShortcutComponent("gui.options.page.asset_packs.button.open_folder", () -> FileOpener.open(new File(mc.getMinecraftDir(), "texturepacks"))))
             .withComponent(new OptionsCategory("gui.options.page.asset_packs.category.textures")
-                .withComponent(new ToggleableOptionComponent<>(mc.gameSettings.animations))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.customAnimations))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.mobVariants))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.customLightmap))
-                .withComponent(new BooleanOptionComponent(mc.gameSettings.enableHolidayTextures))
+                .withComponent(new ToggleableOptionComponent<>(GameSettings.TEXTURE_ANIMATIONS).applyOnRelease())
+                .withComponent(new BooleanOptionComponent(GameSettings.CUSTOM_TEXTURE_ANIMATIONS))
+                .withComponent(new BooleanOptionComponent(GameSettings.MOB_VARIANTS))
+                .withComponent(new BooleanOptionComponent(GameSettings.CUSTOM_LIGHTMAP))
+                .withComponent(new BooleanOptionComponent(GameSettings.ENABLE_HOLIDAY_TEXTURES))
             )
             .withComponent(new ShortcutComponent("gui.options.page.asset_packs.button.apply", mc.texturePackList::refreshIfReady))
             .withComponent(new OptionsCategory("gui.options.page.asset_packs.category.asset_packs.selected")
@@ -308,46 +329,44 @@ public abstract class OptionsPages {
         );
         DEBUG = register(new OptionsPageDebug("gui.options.page.debug.title", Blocks.BEDROCK.getDefaultStack())
             .withComponent(new OptionsCategory("gui.options.page.debug.category.controls")
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyToggleTextureAtlas))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyToggleDebug))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyShowShortcuts))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyReload))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keySwitchGamemode))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyDumpTextures))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyFullbright))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyLightmaps))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyCollisionBoxes))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyChunkBorders))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyClearChat))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyPauseLostFocus))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyToggleItemInfo))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyReloadChunks))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keySmoothLighting))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyReleaseCursor))
-                .withComponent(new KeyBindingComponent(mc.gameSettings.keyLoadChunksQuickly))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_TOGGLE_TEXTURE_ATLAS))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_TOGGLE_DEBUG))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_SHOW_SHORTCUTS))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_RELOAD))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_SWITCH_GAMEMODE))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_DUMP_TEXTURES))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_FULLBRIGHT))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_LIGHTMAPS))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_COLLISION_BOXES))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_CHUNK_BORDERS))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_CLEAR_CHAT))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_PAUSE_LOST_FOCUS))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_TOGGLE_ITEM_INFO))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_RELOAD_CHUNKS))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_SMOOTH_LIGHTING))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_RELEASE_CURSOR))
+                .withComponent(new KeyBindingComponent(GameSettings.KEY_LOAD_CHUNKS_QUICKLY))
             )
             .withComponent(new OptionsCategory("gui.options.page.debug.category.settings")
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.developerMode))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.playerDevModel))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.viewSupportMode))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.alphaMenu))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.lockCamera))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.showDebugScreen))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.showFrameTimes))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.showChunkBorders))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.showCollisionBoxes))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.showItemDebugInfo))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.disableCrashHandler))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.startInFullscreen))
-//                .withComponent(new BooleanOptionComponent(mc.gameSettings.disableShaders))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.loadAllSounds))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.allowSoundOverrides))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.downloadSoundfiles))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.enableDevResourceLoading))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.devModels))
-//                .withComponent(new BooleanOptionComponent(mc.gameSettings.enableMultiDrawRendering))
-                    .withComponent(new ToggleableOptionComponent<>(mc.gameSettings.enableThreadedChunkProvider))
-                    .withComponent(new BooleanOptionComponent(mc.gameSettings.doJCECheck))
+                    .withComponent(new BooleanOptionComponent(GameSettings.DEVELOPER_MODE))
+                    .withComponent(new BooleanOptionComponent(GameSettings.PLAYER_DEV_MODEL))
+                    .withComponent(new BooleanOptionComponent(GameSettings.VIEW_SUPPORT_MODE))
+                    .withComponent(new BooleanOptionComponent(GameSettings.ALPHA_MENU))
+                    .withComponent(new BooleanOptionComponent(GameSettings.LOCK_CAMERA))
+                    .withComponent(new BooleanOptionComponent(GameSettings.SHOW_DEBUG_SCREEN))
+                    .withComponent(new BooleanOptionComponent(GameSettings.SHOW_FRAME_TIMES))
+                    .withComponent(new BooleanOptionComponent(GameSettings.SHOW_CHUNK_BORDERS))
+                    .withComponent(new BooleanOptionComponent(GameSettings.SHOW_COLLISION_BOXES))
+                    .withComponent(new BooleanOptionComponent(GameSettings.SHOW_ITEM_DEBUG_INFO))
+                    .withComponent(new BooleanOptionComponent(GameSettings.DISABLE_CRASH_HANDLER))
+                    .withComponent(new BooleanOptionComponent(GameSettings.START_IN_FULLSCREEN))
+                    .withComponent(new BooleanOptionComponent(GameSettings.LOAD_ALL_SOUNDS))
+                    .withComponent(new BooleanOptionComponent(GameSettings.ALLOW_SOUND_OVERRIDES))
+                    .withComponent(new BooleanOptionComponent(GameSettings.DOWNLOAD_SOUNDFILES))
+                    .withComponent(new BooleanOptionComponent(GameSettings.ENABLE_DEV_RESOURCE_LOADING))
+                    .withComponent(new BooleanOptionComponent(GameSettings.DEV_MODELS))
+                    .withComponent(new ToggleableOptionComponent<>(GameSettings.CHUNK_PROVIDER))
+                    .withComponent(new BooleanOptionComponent(GameSettings.DO_JCE_CHECK))
             )
             .withComponent(new OptionsCategory("gui.options.page.debug.category.utility")
                 .withComponent(new ShortcutComponent("gui.options.page.debug.button.open.model_viewer", () -> {
@@ -424,12 +443,15 @@ public abstract class OptionsPages {
                 .withComponent(new ShortcutComponent("gui.options.page.debug.button.crash.soft", () -> {
                     throw new RuntimeException("Test Soft Exception");
                 }))
-                .withComponent(new ShortcutComponent("gui.options.page.debug.button.crash.hard", () -> {
-                    Minecraft.getMinecraft().gameWindow.displayCrashReport(new UnexpectedThrowable("Test Hard Exception", new Error()), -1);
-                    Minecraft.getMinecraft().hasCrashed = true;
-                    throw new Error();
-                }))
+//                .withComponent(new ShortcutComponent("gui.options.page.debug.button.crash.hard", () -> {
+//                    Minecraft.getMinecraft().gameWindow.displayCrashReport(new UnexpectedThrowable("Test Hard Exception", new Error()), -1);
+//                    Minecraft.getMinecraft().hasCrashed = true;
+//                    throw new Error();
+//                }))
                 .withComponent(new ShortcutComponent("gui.options.page.debug.button.garbage_collect", System::gc))
+                .withComponent(new ShortcutComponent("gui.options.page.debug.button.reload_commands", () ->{
+                    if (Minecraft.getMinecraft().currentWorld != null) Minecraft.getMinecraft().currentWorld.getCommandManager().reload();
+                }))
             ));
     }
 }
\ No newline at end of file
diff --git a/game/client/src/main/java/net/minecraft/client/gui/popup/MessageBoxComponent.java b/game/client/src/main/java/net/minecraft/client/gui/popup/MessageBoxComponent.java
index 1766d8fca..afe087aa1 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/popup/MessageBoxComponent.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/popup/MessageBoxComponent.java
@@ -117,7 +117,6 @@ public class MessageBoxComponent
         this.drawScrollbar(x, y, mouseX, mouseY);
 
         Scissor.enable(x + 1, y + 1, this.getWidth() - 2, this.getHeight() - 2);
-        GLRenderer.popFrame();
 
         // Draw lines
         for (int i = 0; i < this.lines.size(); i++) {
@@ -125,6 +124,7 @@ public class MessageBoxComponent
         }
 
         Scissor.disable();
+        GLRenderer.popFrame();
     }
 
     private boolean mouseInRegion(final int x, final int y, final int mouseX, final int mouseY) {
diff --git a/game/client/src/main/java/net/minecraft/client/gui/popup/PopupScreen.java b/game/client/src/main/java/net/minecraft/client/gui/popup/PopupScreen.java
index 4c37a4cbd..14b851ca1 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/popup/PopupScreen.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/popup/PopupScreen.java
@@ -2,6 +2,7 @@ package net.minecraft.client.gui.popup;
 
 import it.unimi.dsi.fastutil.ints.IntIntPair;
 import net.minecraft.client.gui.Screen;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import org.jetbrains.annotations.NotNull;
@@ -170,7 +171,7 @@ public final class PopupScreen
         GLRenderer.setColor4f(1.0F, 1.0F, 1.0F, 1.0F);
 
         if (this.backgroundColor == null) {
-            final int color = this.mc.gameSettings.guiBackgroundColor.value.getARGB();
+            final int color = GameSettings.GUI_BACKGROUND_COLOR.value.getARGB();
             this.drawGradientRect(0, 0, this.width, this.height, color, color);
         } else {
             this.drawGradientRect(0, 0, this.width, this.height, this.backgroundColor.leftInt(), this.backgroundColor.rightInt());
diff --git a/game/client/src/main/java/net/minecraft/client/gui/server/ScreenSelectServer.java b/game/client/src/main/java/net/minecraft/client/gui/server/ScreenSelectServer.java
index 50e09f2db..82aaec988 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/server/ScreenSelectServer.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/server/ScreenSelectServer.java
@@ -9,6 +9,7 @@ import net.minecraft.client.gui.paged.PageRegistry;
 import net.minecraft.client.gui.paged.ScreenPaged;
 import net.minecraft.client.gui.popup.PopupBuilder;
 import net.minecraft.client.gui.popup.PopupScreen;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.Scissor;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.Shaders;
@@ -252,8 +253,8 @@ public class ScreenSelectServer extends ScreenPaged {
     }
 
     public void joinServer(@NotNull ServerAddress address) {
-        this.mc.gameSettings.lastServer.value = address.toString().replaceAll(":", "_");
-        this.mc.gameSettings.saveOptions();
+        GameSettings.LAST_SERVER.value = address.toString().replaceAll(":", "_");
+        GameSettings.saveOptions();
         this.mc.displayScreen(new ScreenConnecting(this.mc, address.getIP(), address.getPort()));
         freeResources();
     }
@@ -466,7 +467,7 @@ public class ScreenSelectServer extends ScreenPaged {
 
             tessellator.draw();
         } else {
-            final int color = this.mc.gameSettings.guiBackgroundColor.value.getARGB();
+            final int color = GameSettings.GUI_BACKGROUND_COLOR.value.getARGB();
             this.drawGradientRect(0, 0, this.width, this.height, color, color);
             this.drawRect(0, 0, this.width, this.top, 0x5F000000);
             this.drawRect(0, this.bottom, this.width, this.height, 0x5F000000);
diff --git a/game/client/src/main/java/net/minecraft/client/gui/worldsettings/CategoryMobSpawningComponent.java b/game/client/src/main/java/net/minecraft/client/gui/worldsettings/CategoryMobSpawningComponent.java
new file mode 100644
index 000000000..b610bd657
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/gui/worldsettings/CategoryMobSpawningComponent.java
@@ -0,0 +1,101 @@
+package net.minecraft.client.gui.worldsettings;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.SwitchElement;
+import net.minecraft.client.render.window.CursorShape;
+import net.minecraft.core.lang.I18n;
+import net.minecraft.core.world.settings.WorldConfiguration;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class CategoryMobSpawningComponent extends ButtonComponent {
+    private @Nullable WorldConfiguration worldConfiguration = null;
+    private final @NotNull SwitchElement button;
+    private final @NotNull Type type;
+    public CategoryMobSpawningComponent(@NotNull Type type) {
+        super(type.getKey(), null);
+        this.type = type;
+
+        this.button = new SwitchElement(0, 0, 0, 150, 20, true,
+            I18n.getInstance().translateKey("gui.world_settings.page.mob_spawning.button.on"),
+            I18n.getInstance().translateKey("gui.world_settings.page.mob_spawning.button.off"));
+        this.button.setOn(true);
+    }
+
+    public void setSpawnConfiguration(final @NotNull WorldConfiguration worldConfiguration) {
+        this.worldConfiguration = worldConfiguration;
+    }
+
+    @Override
+    public void resetValue() {
+        this.type.setValue(this.worldConfiguration, true);
+        onChange();
+    }
+
+    @Override
+    public void init(Minecraft mc) {
+        onChange();
+    }
+
+    @Override
+    public boolean isDefault() {
+        return this.button.isOn();
+    }
+
+    protected void onChange() {
+        this.button.setOn(this.type.getValue(this.worldConfiguration));
+    }
+
+    @Override
+    protected void buttonClicked(int mouseButton, int x, int y, int width, int height, int relativeMouseX, int relativeMouseY) {
+        this.type.setValue(this.worldConfiguration, !this.type.getValue(this.worldConfiguration));
+        onChange();
+    }
+
+    @Override
+    protected void renderButton(final int x, final int y, final int relativeButtonX, final int relativeButtonY, final int buttonWidth, final int buttonHeight, final int relativeMouseX, final int relativeMouseY) {
+        super.renderButton(x, y, relativeButtonX, relativeButtonY, buttonWidth, buttonHeight, relativeMouseX, relativeMouseY);
+
+        this.button.xPosition = x + relativeButtonX;
+        this.button.yPosition = y + relativeButtonY;
+        this.button.width = buttonWidth;
+        this.button.height = buttonHeight;
+
+        this.button.drawButton(mc, x + relativeMouseX, y + relativeMouseY);
+
+        if (mc.currentScreen != null && relativeMouseX >= relativeButtonX && relativeMouseX < relativeButtonX + buttonWidth && relativeMouseY >= relativeButtonY && relativeButtonY < relativeButtonY + buttonHeight) {
+            mc.currentScreen.setDesiredCursor(CursorShape.HAND);
+        }
+    }
+
+    public enum Type {
+        HOSTILE("hostile"),
+        PASSIVE("passive");
+
+        private final @NotNull String key;
+
+        Type(@NotNull String key) {
+            this.key = "gui.world_settings.page.mob_spawning." + key;
+        }
+
+        public @NotNull String getKey() {
+            return this.key;
+        }
+
+        public void setValue(@NotNull WorldConfiguration worldConfiguration, boolean flag) {
+            if (this == HOSTILE) {
+                worldConfiguration.getSpawnerConfig().setHostileSpawning(flag);
+            } else {
+                worldConfiguration.getSpawnerConfig().setPassiveSpawning(flag);
+            }
+        }
+
+        public boolean getValue(@NotNull WorldConfiguration worldConfiguration) {
+            if (this == HOSTILE) {
+                return worldConfiguration.getSpawnerConfig().allowHostile;
+            } else {
+                return worldConfiguration.getSpawnerConfig().allowPassive;
+            }
+        }
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/gui/worldsettings/EntryMobSpawningComponent.java b/game/client/src/main/java/net/minecraft/client/gui/worldsettings/EntryMobSpawningComponent.java
new file mode 100644
index 000000000..4116250e8
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/gui/worldsettings/EntryMobSpawningComponent.java
@@ -0,0 +1,73 @@
+package net.minecraft.client.gui.worldsettings;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.SwitchElement;
+import net.minecraft.client.render.window.CursorShape;
+import net.minecraft.core.entity.EntityDispatcher;
+import net.minecraft.core.lang.I18n;
+import net.minecraft.core.world.settings.WorldConfiguration;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Objects;
+
+public class EntryMobSpawningComponent extends ButtonComponent{
+    private final @NotNull EntityDispatcher.EntityDispatcherEntry<?> entry;
+    private @Nullable WorldConfiguration worldConfiguration = null;
+    private final @NotNull SwitchElement button;
+    public EntryMobSpawningComponent(@NotNull EntityDispatcher.EntityDispatcherEntry<?> entry) {
+        super(Objects.requireNonNullElse(entry.nameKey, entry.namespaceID.toString()), null);
+        this.entry = entry;
+
+        this.button = new SwitchElement(0, 0, 0, 150, 20, true,
+            I18n.getInstance().translateKey("gui.world_settings.page.mob_spawning.button.on"),
+            I18n.getInstance().translateKey("gui.world_settings.page.mob_spawning.button.off"));
+        this.button.setOn(true);
+    }
+
+    public void setSpawnConfiguration(final @NotNull WorldConfiguration worldConfiguration) {
+        this.worldConfiguration = worldConfiguration;
+    }
+
+    @Override
+    public void resetValue() {
+        this.worldConfiguration.getSpawnerConfig().setMobSpawn(this.entry.namespaceID, true);
+        onChange();
+    }
+
+    @Override
+    public void init(Minecraft mc) {
+        onChange();
+    }
+
+    @Override
+    public boolean isDefault() {
+        return this.button.isOn();
+    }
+
+    @Override
+    protected void buttonClicked(int mouseButton, int x, int y, int width, int height, int relativeMouseX, int relativeMouseY) {
+        this.worldConfiguration.getSpawnerConfig().setMobSpawn(this.entry.namespaceID, this.worldConfiguration.getSpawnerConfig().canMobSpawn(this.entry.namespaceID));
+        onChange();
+    }
+
+    protected void onChange() {
+        this.button.setOn(this.worldConfiguration.getSpawnerConfig().canMobSpawn(this.entry.namespaceID));
+    }
+
+    @Override
+    protected void renderButton(final int x, final int y, final int relativeButtonX, final int relativeButtonY, final int buttonWidth, final int buttonHeight, final int relativeMouseX, final int relativeMouseY) {
+        super.renderButton(x, y, relativeButtonX, relativeButtonY, buttonWidth, buttonHeight, relativeMouseX, relativeMouseY);
+
+        this.button.xPosition = x + relativeButtonX;
+        this.button.yPosition = y + relativeButtonY;
+        this.button.width = buttonWidth;
+        this.button.height = buttonHeight;
+
+        this.button.drawButton(mc, x + relativeMouseX, y + relativeMouseY);
+
+        if (mc.currentScreen != null && relativeMouseX >= relativeButtonX && relativeMouseX < relativeButtonX + buttonWidth && relativeMouseY >= relativeButtonY && relativeButtonY < relativeButtonY + buttonHeight) {
+            mc.currentScreen.setDesiredCursor(CursorShape.HAND);
+        }
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/gui/worldsettings/ScreenWorldSettings.java b/game/client/src/main/java/net/minecraft/client/gui/worldsettings/ScreenWorldSettings.java
index 87c7514f6..3baacf81f 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/worldsettings/ScreenWorldSettings.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/worldsettings/ScreenWorldSettings.java
@@ -8,6 +8,8 @@ import net.minecraft.client.gui.paged.ScreenPaged;
 import net.minecraft.core.data.gamerule.GameRule;
 import net.minecraft.core.data.gamerule.GameRuleBoolean;
 import net.minecraft.core.data.registry.Registries;
+import net.minecraft.core.entity.EntityDispatcher;
+import net.minecraft.core.entity.Mob;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.world.settings.WorldConfiguration;
 import org.jetbrains.annotations.NotNull;
@@ -16,10 +18,10 @@ import org.jetbrains.annotations.Nullable;
 import java.util.List;
 
 public class ScreenWorldSettings
-    extends ScreenPaged
-{
+    extends ScreenPaged {
     public static final @NotNull PageRegistry CREATE_WORLD_PAGES = new PageRegistry();
     public static final @NotNull Page PAGE_GAME_RULES = CREATE_WORLD_PAGES.register(new Page("gui.world_settings.page.game_rules.title", Items.PAPER.getDefaultStack()));
+
     static {
         for (final @NotNull GameRule<?> gameRule : Registries.GAME_RULES) {
             if (gameRule instanceof GameRuleBoolean) {
@@ -27,29 +29,55 @@ public class ScreenWorldSettings
             }
         }
     }
+
     public static final @NotNull Page PAGE_WORLD_SETTINGS = CREATE_WORLD_PAGES.register(
-            new Page("gui.world_settings.page.world_settings.title", Items.PAINTBRUSH.getDefaultStack())
-                    .withComponent(new WorldTypeButtonComponent("gui.world_settings.label.world_type", null))
+        new Page("gui.world_settings.page.world_settings.title", Items.PAINTBRUSH.getDefaultStack())
+            .withComponent(new WorldTypeButtonComponent("gui.world_settings.label.world_type", null))
+            .withComponent(new StartingBiomeButtonComponent("gui.world_settings.label.starting_biome", null))
+    );
+    public static final @NotNull Page PAGE_MOB_SPAWNING = CREATE_WORLD_PAGES.register(
+        new Page("gui.world_settings.page.mob_spawning.title", Items.EGG_CHICKEN.getDefaultStack())
+            .withComponent(new CategoryMobSpawningComponent(CategoryMobSpawningComponent.Type.HOSTILE))
+            .withComponent(new CategoryMobSpawningComponent(CategoryMobSpawningComponent.Type.PASSIVE))
     );
 
+    static {
+        for (var entry : EntityDispatcher.getInstance().entries) {
+            if (Mob.class.isAssignableFrom(entry.entityClass) && entry.nameKey != null) { // Probably have something better than checking if name key is null
+                PAGE_MOB_SPAWNING.withComponent(new EntryMobSpawningComponent(entry));
+            }
+        }
+    }
+
     private final @NotNull WorldConfiguration worldConfiguration;
 
     public ScreenWorldSettings(final @Nullable Screen parent, final @NotNull WorldConfiguration worldConfiguration) {
-        super(parent, CREATE_WORLD_PAGES, PAGE_GAME_RULES, "gui.world_settings.label.title", new String[] { "gui.world_settings.button.done" });
+        super(parent, CREATE_WORLD_PAGES, PAGE_GAME_RULES, "gui.world_settings.label.title", new String[]{"gui.world_settings.button.done"});
 
         this.worldConfiguration = worldConfiguration;
 
         final List<PageComponent> gameRulesPageComponents = PAGE_GAME_RULES.getComponents();
-        for (final @NotNull  PageComponent component : gameRulesPageComponents) {
-            if (component instanceof BooleanGameRuleComponent) {
-                ((BooleanGameRuleComponent) component).setGameRuleCollection(worldConfiguration.getGameRuleCollection());
+        for (final @NotNull PageComponent component : gameRulesPageComponents) {
+            if (component instanceof BooleanGameRuleComponent ruleComponent) {
+                ruleComponent.setGameRuleCollection(worldConfiguration.getGameRuleCollection());
             }
         }
 
         final List<PageComponent> worldSettingsPageComponents = PAGE_WORLD_SETTINGS.getComponents();
         for (final @NotNull PageComponent component : worldSettingsPageComponents) {
-            if (component instanceof WorldTypeButtonComponent) {
-                ((WorldTypeButtonComponent) component).setWorldConfiguration(worldConfiguration);
+            if (component instanceof WorldTypeButtonComponent typeButtonComponent) {
+                typeButtonComponent.setWorldConfiguration(worldConfiguration);
+            } else if (component instanceof StartingBiomeButtonComponent startingBiomeButtonComponent) {
+                startingBiomeButtonComponent.setWorldConfiguration(worldConfiguration);
+            }
+        }
+
+        final List<PageComponent> mobSpawnPageComponents = PAGE_MOB_SPAWNING.getComponents();
+        for (final @NotNull PageComponent component : mobSpawnPageComponents) {
+            if (component instanceof EntryMobSpawningComponent mobSpawningComponent) {
+                mobSpawningComponent.setSpawnConfiguration(worldConfiguration);
+            } else if (component instanceof CategoryMobSpawningComponent categoryComponent) {
+                categoryComponent.setSpawnConfiguration(worldConfiguration);
             }
         }
     }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/worldsettings/StartingBiomeButtonComponent.java b/game/client/src/main/java/net/minecraft/client/gui/worldsettings/StartingBiomeButtonComponent.java
new file mode 100644
index 000000000..fe9c119b5
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/gui/worldsettings/StartingBiomeButtonComponent.java
@@ -0,0 +1,121 @@
+package net.minecraft.client.gui.worldsettings;
+
+import net.minecraft.client.gui.ButtonElement;
+import net.minecraft.client.gui.popup.PopupBuilder;
+import net.minecraft.client.gui.popup.PopupScreen;
+import net.minecraft.client.render.window.CursorShape;
+import net.minecraft.core.lang.I18n;
+import net.minecraft.core.world.Dimension;
+import net.minecraft.core.world.biome.Biome;
+import net.minecraft.core.world.settings.WorldConfiguration;
+import net.minecraft.core.world.type.WorldTypeGroups;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Objects;
+
+public class StartingBiomeButtonComponent
+    extends ButtonComponent {
+    private @Nullable WorldConfiguration worldConfiguration = null;
+    private final @NotNull ButtonElement button;
+    private @Nullable WorldTypeGroups.Group lastGroup = null;
+
+    public StartingBiomeButtonComponent(final @NotNull String translationKey, final @Nullable String tooltipTranslationKey) {
+        super(translationKey, tooltipTranslationKey);
+
+        this.button = new ButtonElement(0, 0, 0, 150, 20, "");
+    }
+
+    public void setWorldConfiguration(final @NotNull WorldConfiguration worldConfiguration) {
+        this.worldConfiguration = worldConfiguration;
+        Biome biome = this.worldConfiguration.getStartingBiome();
+        this.button.displayString = I18n.getInstance().translateKey(biome == null ? "gui.world_settings.page.starting_biome.biome.none" : biome.translationKey);
+    }
+
+    @Override
+    public void resetValue() {
+        Objects.requireNonNull(this.worldConfiguration).setStartingBiome(null);
+        Biome biome = this.worldConfiguration.getStartingBiome();
+        this.button.displayString = I18n.getInstance().translateKey(biome == null ? "gui.world_settings.page.starting_biome.biome.none" : biome.translationKey);
+    }
+
+    @Override
+    public boolean isDefault() {
+        return Objects.requireNonNull(this.worldConfiguration).getStartingBiome() == null;
+    }
+
+    @Override
+    protected void buttonClicked(final int mouseButton, final int x, final int y, final int width, final int height, final int relativeMouseX, final int relativeMouseY) {
+        final I18n i18n = I18n.getInstance();
+
+        Biome[] biomes = this.worldConfiguration.getWorldTypeGroup().get(Dimension.OVERWORLD).allBiomes();
+
+        final @NotNull String @NotNull [] keys = new String[biomes.length + 1];
+        for (int i = 0; i < keys.length; i++) {
+            int selected = i - 1;
+
+            Biome biome;
+            if (selected >= 0) {
+                biome = biomes[selected];
+            } else {
+                biome = null;
+            }
+
+            keys[i] = i18n.translateKey(biome == null ? "gui.world_settings.page.starting_biome.biome.none" : biome.translationKey);
+        }
+
+        int b = 0;
+        if (this.worldConfiguration.getStartingBiome() == null) {
+            b = 0;
+        } else {
+            for (int i = 0; i < biomes.length; i++) {
+                if (biomes[i] == this.worldConfiguration.getStartingBiome()) {
+                    b = i + 1;
+                    break;
+                }
+            }
+        }
+
+        final PopupScreen popup = new PopupBuilder(Objects.requireNonNull(mc.currentScreen), 150)
+            .closeOnEsc(0)
+            .closeOnClickOut(0)
+            .withLabel("gui.world_settings.label.starting_biome")
+            .withList("biomeList", 140, keys, null, b, true)
+            .withOnCloseListener((statusCode, results) -> {
+                if (statusCode == 1) {
+                    int selected = (Integer) results.get("biomeList") - 1;
+                    Biome biome;
+                    if (selected >= 0) {
+                        biome = biomes[selected];
+                    } else {
+                        biome = null;
+                    }
+                    this.worldConfiguration.setStartingBiome(biome);
+                    this.button.displayString = I18n.getInstance().translateKey(biome == null ? "gui.world_settings.page.starting_biome.biome.none" : biome.translationKey);
+                }
+            })
+            .build();
+        mc.displayScreen(popup);
+    }
+
+    @Override
+    protected void renderButton(final int x, final int y, final int relativeButtonX, final int relativeButtonY, final int buttonWidth, final int buttonHeight, final int relativeMouseX, final int relativeMouseY) {
+        if (worldConfiguration.getWorldTypeGroup() != lastGroup) {
+            lastGroup = worldConfiguration.getWorldTypeGroup();
+            resetValue();
+        }
+
+        super.renderButton(x, y, relativeButtonX, relativeButtonY, buttonWidth, buttonHeight, relativeMouseX, relativeMouseY);
+
+        this.button.xPosition = x + relativeButtonX;
+        this.button.yPosition = y + relativeButtonY;
+        this.button.width = buttonWidth;
+        this.button.height = buttonHeight;
+
+        this.button.drawButton(mc, x + relativeMouseX, y + relativeMouseY);
+
+        if (mc.currentScreen != null && relativeMouseX >= relativeButtonX && relativeMouseX < relativeButtonX + buttonWidth && relativeMouseY >= relativeButtonY && relativeButtonY < relativeButtonY + buttonHeight) {
+            mc.currentScreen.setDesiredCursor(CursorShape.HAND);
+        }
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/input/PlayerInput.java b/game/client/src/main/java/net/minecraft/client/input/PlayerInput.java
index 0a3e3ccc9..49ad359e7 100644
--- a/game/client/src/main/java/net/minecraft/client/input/PlayerInput.java
+++ b/game/client/src/main/java/net/minecraft/client/input/PlayerInput.java
@@ -2,14 +2,12 @@ package net.minecraft.client.input;
 
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.option.GameSettings;
-import net.minecraft.client.option.KeyBinding;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.util.helper.MathHelper;
 
 public class PlayerInput {
 
 	public final Minecraft mc;
-	public final GameSettings gameSettings;
 	
 	private boolean isAutoWalkOn = false;
 	
@@ -31,97 +29,96 @@ public class PlayerInput {
 
 	public PlayerInput(Minecraft minecraft) {
 		this.mc = minecraft;
-		this.gameSettings = mc.gameSettings;
 	}
 
 	public void keyEvent(int keyCode, int mouseCode, boolean pressed) {
-		if(mc.currentScreen != null) {
+		if(this.mc.currentScreen != null) {
 			return;
 		}
 		
-		if(gameSettings.keySneak.isKeyOrMouse(keyCode, mouseCode)) {
-			if(gameSettings.sneakToggle.value && !mc.thePlayer.noPhysics) {
+		if(GameSettings.KEY_SNEAK.isKeyOrMouse(keyCode, mouseCode)) {
+			if(GameSettings.SNEAK_TOGGLE.value && !this.mc.thePlayer.noPhysics) {
 				if(pressed) {
-					sneak = !sneak;
+                    this.sneak = !this.sneak;
 				}
 			}else {
-				sneak = pressed;
+                this.sneak = pressed;
 			}
 		}
 		
-		if(gameSettings.keyForward.isKeyOrMouse(keyCode, mouseCode) ) {
-			pressedForward = pressed;
-			isAutoWalkOn = false;
+		if(GameSettings.KEY_FORWARD.isKeyOrMouse(keyCode, mouseCode) ) {
+            this.pressedForward = pressed;
+            this.isAutoWalkOn = false;
 		}
-		if(gameSettings.keyBack.isKeyOrMouse(keyCode, mouseCode)) {
-			pressedBackward = pressed;
-			isAutoWalkOn = false;
+		if(GameSettings.KEY_BACK.isKeyOrMouse(keyCode, mouseCode)) {
+            this.pressedBackward = pressed;
+            this.isAutoWalkOn = false;
 		}
-		if(gameSettings.keyLeft.isKeyOrMouse(keyCode, mouseCode)) {
-			pressedLeft = pressed;
+		if(GameSettings.KEY_LEFT.isKeyOrMouse(keyCode, mouseCode)) {
+            this.pressedLeft = pressed;
 		}
-		if(gameSettings.keyRight.isKeyOrMouse(keyCode, mouseCode)) {
-			pressedRight = pressed;
+		if(GameSettings.KEY_RIGHT.isKeyOrMouse(keyCode, mouseCode)) {
+            this.pressedRight = pressed;
 		}
-		if(gameSettings.keyJump.isKeyOrMouse(keyCode, mouseCode)) {
-			pressedJump = pressed;
+		if(GameSettings.KEY_JUMP.isKeyOrMouse(keyCode, mouseCode)) {
+            this.pressedJump = pressed;
 		}
 
-		if(gameSettings.keyAutoWalk.isKeyOrMouse(keyCode, mouseCode) && pressed) {
-			isAutoWalkOn = true;
+		if(GameSettings.KEY_AUTO_WALK.isKeyOrMouse(keyCode, mouseCode) && pressed) {
+            this.isAutoWalkOn = true;
 		}
 
-		if(gameSettings.keyEasyBridge.isKeyOrMouse(keyCode, mouseCode) && pressed) {
-			gameSettings.easyBridge.toggle();
-			mc.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(gameSettings.easyBridge);
+		if(GameSettings.KEY_EASY_BRIDGE.isKeyOrMouse(keyCode, mouseCode) && pressed) {
+			GameSettings.EASY_BRIDGE.toggle();
+            this.mc.hudIngame.heldItemTooltipElement.setOptionNameAndValueString(GameSettings.EASY_BRIDGE);
 		}
 	}
 
 	public void onGameUnfocused() {
-		pressedBackward = false;
-		pressedForward = false;
-		pressedLeft = false;
-		pressedRight = false;
-		
-		pressedJump = false;
+        this.pressedBackward = false;
+        this.pressedForward = false;
+        this.pressedLeft = false;
+        this.pressedRight = false;
+
+        this.pressedJump = false;
 	}
 	
 	public void onGameFocused() {
-		if(!gameSettings.sneakToggle.value) {
-			sneak = gameSettings.keySneak.isPressed();
+		if(!GameSettings.SNEAK_TOGGLE.value) {
+            this.sneak = GameSettings.KEY_SNEAK.isPressed();
 		}
 	}
 
 	public void tick(Player entityplayer) {
-		moveStrafe = 0.0f;
-		moveForward = 0.0f;
-		jump = false;
+        this.moveStrafe = 0.0f;
+        this.moveForward = 0.0f;
+        this.jump = false;
 
-		if(gameSettings.mc.currentScreen == null && mc.controllerInput != null) {
-			moveForward = -mc.controllerInput.joyLeft.getY();
-			moveStrafe = -mc.controllerInput.joyLeft.getX();
-			jump = mc.controllerInput.buttonA.isPressed();
-			if (mc.thePlayer.noPhysics) {
-				sneak = mc.controllerInput.joyRight.getButton().isPressed();
+		if(this.mc.currentScreen == null && this.mc.controllerInput != null) {
+            this.moveForward = -this.mc.controllerInput.joyLeft.getY();
+            this.moveStrafe = -this.mc.controllerInput.joyLeft.getX();
+            this.jump = this.mc.controllerInput.buttonA.isPressed();
+			if (this.mc.thePlayer.noPhysics) {
+                this.sneak = this.mc.controllerInput.joyRight.getButton().isPressed();
 			} else {
-				if(mc.controllerInput.joyRight.getButton().pressedThisFrame()) {
-					sneak = !sneak;
+				if(this.mc.controllerInput.joyRight.getButton().pressedThisFrame()) {
+                    this.sneak = !this.sneak;
 				}
 			}
 		}
 
-		if(pressedForward || isAutoWalkOn) moveForward++;
-		if(pressedBackward) moveForward--;
-		if(pressedLeft) moveStrafe++;
-		if(pressedRight) moveStrafe--;
-		
-		jump |= pressedJump;
-		moveForward = MathHelper.clamp(moveForward, -1, 1);
-		moveStrafe = MathHelper.clamp(moveStrafe, -1, 1);
+		if(this.pressedForward || this.isAutoWalkOn) this.moveForward++;
+		if(this.pressedBackward) this.moveForward--;
+		if(this.pressedLeft) this.moveStrafe++;
+		if(this.pressedRight) this.moveStrafe--;
+
+        this.jump |= this.pressedJump;
+        this.moveForward = MathHelper.clamp(this.moveForward, -1, 1);
+        this.moveStrafe = MathHelper.clamp(this.moveStrafe, -1, 1);
 
 		if(entityplayer.isSneaking() && !entityplayer.noPhysics) {
-			moveStrafe *= 0.3;
-			moveForward *= 0.3;
+            this.moveStrafe *= 0.3f;
+            this.moveForward *= 0.3f;
 		}
 	}
 }
diff --git a/game/client/src/main/java/net/minecraft/client/input/controller/ControllerInput.java b/game/client/src/main/java/net/minecraft/client/input/controller/ControllerInput.java
index 85a4a8930..5250b950e 100644
--- a/game/client/src/main/java/net/minecraft/client/input/controller/ControllerInput.java
+++ b/game/client/src/main/java/net/minecraft/client/input/controller/ControllerInput.java
@@ -4,6 +4,7 @@ import com.b100.utils.ReflectUtils;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.container.ScreenContainerAbstract;
 import net.minecraft.client.input.glfw.GlfwGamepad;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.core.player.inventory.slot.Slot;
 import net.minecraft.core.util.helper.Time;
 import org.jetbrains.annotations.NotNull;
@@ -57,109 +58,109 @@ public class ControllerInput {
         IButtonListener defaultButtonListener = controller::isButtonPressed;
         IJoystickListener defaultJoystickListener = controller::getAxisValue;
 
-        joyLeft = new Joystick(translateAxis(type, GLFW.GLFW_GAMEPAD_AXIS_LEFT_X), GLFW.GLFW_GAMEPAD_AXIS_LEFT_X, GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y, defaultJoystickListener, new Button(translateBtn(type, GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB), GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB, defaultButtonListener), minecraft.gameSettings.controllerDeadzoneLeft);
-        joyRight = new Joystick(translateAxis(type, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X), GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y, defaultJoystickListener, new Button(translateBtn(type, GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB), GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, defaultButtonListener), minecraft.gameSettings.controllerDeadzoneRight);
+        this.joyLeft = new Joystick(translateAxis(this.type, GLFW.GLFW_GAMEPAD_AXIS_LEFT_X), GLFW.GLFW_GAMEPAD_AXIS_LEFT_X, GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y, defaultJoystickListener, new Button(translateBtn(this.type, GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB), GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB, defaultButtonListener), GameSettings.CONTROLLER_DEADZONE_LEFT);
+        this.joyRight = new Joystick(translateAxis(this.type, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X), GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y, defaultJoystickListener, new Button(translateBtn(this.type, GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB), GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, defaultButtonListener), GameSettings.CONTROLLER_DEADZONE_RIGHT);
 
-        buttonBack = new Button(translateBtn(type, GLFW.GLFW_GAMEPAD_BUTTON_BACK), GLFW.GLFW_GAMEPAD_BUTTON_BACK, defaultButtonListener);
-        buttonStart = new Button(translateBtn(type, GLFW.GLFW_GAMEPAD_BUTTON_START), GLFW.GLFW_GAMEPAD_BUTTON_START, defaultButtonListener);
+        this.buttonBack = new Button(translateBtn(this.type, GLFW.GLFW_GAMEPAD_BUTTON_BACK), GLFW.GLFW_GAMEPAD_BUTTON_BACK, defaultButtonListener);
+        this.buttonStart = new Button(translateBtn(this.type, GLFW.GLFW_GAMEPAD_BUTTON_START), GLFW.GLFW_GAMEPAD_BUTTON_START, defaultButtonListener);
 
-        if (minecraft.gameSettings.controllerSwapAB.value) {
-            buttonA = new Button(translateBtn(type, GLFW.GLFW_GAMEPAD_BUTTON_A), GLFW.GLFW_GAMEPAD_BUTTON_B, defaultButtonListener);
-            buttonB = new Button(translateBtn(type, GLFW.GLFW_GAMEPAD_BUTTON_B), GLFW.GLFW_GAMEPAD_BUTTON_A, defaultButtonListener);
+        if (GameSettings.CONTROLLER_SWAP_AB.value) {
+            this.buttonA = new Button(translateBtn(this.type, GLFW.GLFW_GAMEPAD_BUTTON_A), GLFW.GLFW_GAMEPAD_BUTTON_B, defaultButtonListener);
+            this.buttonB = new Button(translateBtn(this.type, GLFW.GLFW_GAMEPAD_BUTTON_B), GLFW.GLFW_GAMEPAD_BUTTON_A, defaultButtonListener);
         } else {
-            buttonA = new Button(translateBtn(type, GLFW.GLFW_GAMEPAD_BUTTON_A), GLFW.GLFW_GAMEPAD_BUTTON_A, defaultButtonListener);
-            buttonB = new Button(translateBtn(type, GLFW.GLFW_GAMEPAD_BUTTON_B), GLFW.GLFW_GAMEPAD_BUTTON_B, defaultButtonListener);
+            this.buttonA = new Button(translateBtn(this.type, GLFW.GLFW_GAMEPAD_BUTTON_A), GLFW.GLFW_GAMEPAD_BUTTON_A, defaultButtonListener);
+            this.buttonB = new Button(translateBtn(this.type, GLFW.GLFW_GAMEPAD_BUTTON_B), GLFW.GLFW_GAMEPAD_BUTTON_B, defaultButtonListener);
         }
 
-        if (minecraft.gameSettings.controllerSwapXY.value) {
-            buttonX = new Button(translateBtn(type, GLFW.GLFW_GAMEPAD_BUTTON_X), GLFW.GLFW_GAMEPAD_BUTTON_Y, defaultButtonListener);
-            buttonY = new Button(translateBtn(type, GLFW.GLFW_GAMEPAD_BUTTON_Y), GLFW.GLFW_GAMEPAD_BUTTON_X, defaultButtonListener);
+        if (GameSettings.CONTROLLER_SWAP_XY.value) {
+            this.buttonX = new Button(translateBtn(this.type, GLFW.GLFW_GAMEPAD_BUTTON_X), GLFW.GLFW_GAMEPAD_BUTTON_Y, defaultButtonListener);
+            this.buttonY = new Button(translateBtn(this.type, GLFW.GLFW_GAMEPAD_BUTTON_Y), GLFW.GLFW_GAMEPAD_BUTTON_X, defaultButtonListener);
         } else {
-            buttonX = new Button(translateBtn(type, GLFW.GLFW_GAMEPAD_BUTTON_X), GLFW.GLFW_GAMEPAD_BUTTON_X, defaultButtonListener);
-            buttonY = new Button(translateBtn(type, GLFW.GLFW_GAMEPAD_BUTTON_Y), GLFW.GLFW_GAMEPAD_BUTTON_Y, defaultButtonListener);
+            this.buttonX = new Button(translateBtn(this.type, GLFW.GLFW_GAMEPAD_BUTTON_X), GLFW.GLFW_GAMEPAD_BUTTON_X, defaultButtonListener);
+            this.buttonY = new Button(translateBtn(this.type, GLFW.GLFW_GAMEPAD_BUTTON_Y), GLFW.GLFW_GAMEPAD_BUTTON_Y, defaultButtonListener);
         }
 
-        if (minecraft.gameSettings.controllerSwapShoulderButtons.value) {
-            buttonLeftShoulder = new Button(translateBtn(type, GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER), GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER, defaultButtonListener);
-            buttonRightShoulder = new Button(translateBtn(type, GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER), GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER, defaultButtonListener);
+        if (GameSettings.CONTROLLER_SWAP_SHOULDER_BUTTONS.value) {
+            this.buttonLeftShoulder = new Button(translateBtn(this.type, GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER), GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER, defaultButtonListener);
+            this.buttonRightShoulder = new Button(translateBtn(this.type, GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER), GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER, defaultButtonListener);
 
-            buttonLeftTrigger = new Button(translateAxis(type, GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER), GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, (axis) -> this.controller.getAxisValue(axis) > 0.5f);
-            buttonRightTrigger = new Button(translateAxis(type, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER), GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, (axis) -> this.controller.getAxisValue(axis) > 0.5f);
+            this.buttonLeftTrigger = new Button(translateAxis(this.type, GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER), GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, (axis) -> this.controller.getAxisValue(axis) > 0.5f);
+            this.buttonRightTrigger = new Button(translateAxis(this.type, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER), GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, (axis) -> this.controller.getAxisValue(axis) > 0.5f);
         } else {
-            buttonLeftShoulder = new Button(translateBtn(type, GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER), GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER, defaultButtonListener);
-            buttonRightShoulder = new Button(translateBtn(type, GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER), GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER, defaultButtonListener);
+            this.buttonLeftShoulder = new Button(translateBtn(this.type, GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER), GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER, defaultButtonListener);
+            this.buttonRightShoulder = new Button(translateBtn(this.type, GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER), GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER, defaultButtonListener);
 
-            buttonLeftTrigger = new Button(translateAxis(type, GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER), GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, (axis) -> this.controller.getAxisValue(axis) > 0.5f);
-            buttonRightTrigger = new Button(translateAxis(type, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER), GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, (axis) -> this.controller.getAxisValue(axis) > 0.5f);
+            this.buttonLeftTrigger = new Button(translateAxis(this.type, GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER), GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, (axis) -> this.controller.getAxisValue(axis) > 0.5f);
+            this.buttonRightTrigger = new Button(translateAxis(this.type, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER), GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, (axis) -> this.controller.getAxisValue(axis) > 0.5f);
         }
 
-        digitalPad = new DigitalPad(
+        this.digitalPad = new DigitalPad(
             new Button("Digital Up", GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP, defaultButtonListener),
             new Button("Digital Left", GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT, defaultButtonListener),
             new Button("Digital Down", GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN, defaultButtonListener),
             new Button("Digital Right", GLFW.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT, defaultButtonListener)
         );
 
-        buttons = ReflectUtils.getAllObjects(ControllerInput.class, Button.class, this);
-        joysticks = ReflectUtils.getAllObjects(ControllerInput.class, Joystick.class, this);
+        this.buttons = ReflectUtils.getAllObjects(ControllerInput.class, Button.class, this);
+        this.joysticks = ReflectUtils.getAllObjects(ControllerInput.class, Joystick.class, this);
     }
 
     public String getGUID() {
-        return controller.getGuid();
+        return this.controller.getGuid();
     }
 
     public ControllerType getType() {
-        return type;
+        return this.type;
     }
 
     public void moveCursor() {
-        if (lockCursor) return;
-        double speed = 300 * Time.delta * (minecraft.gameSettings.controllerMenuSensitivity.value + 0.5f);
+        if (this.lockCursor) return;
+        double speed = 300 * Time.delta * (GameSettings.CONTROLLER_MENU_SENSITIVITY.value + 0.5f);
 
-        cursorX += ((Math.pow(joyLeft.getX(), 3.0f) + joyLeft.getX()) / 2.0f) * speed;
-        cursorY += ((Math.pow(joyLeft.getY(), 3.0f) + joyLeft.getY()) / 2.0f) * speed;
+        this.cursorX += ((Math.pow(this.joyLeft.getX(), 3.0f) + this.joyLeft.getX()) / 2.0f) * speed;
+        this.cursorY += ((Math.pow(this.joyLeft.getY(), 3.0f) + this.joyLeft.getY()) / 2.0f) * speed;
 
-        cursorX = Math.max(cursorX, 0);
-        cursorY = Math.max(cursorY, 0);
+        this.cursorX = Math.max(this.cursorX, 0);
+        this.cursorY = Math.max(this.cursorY, 0);
 
-        cursorX = Math.min(cursorX, minecraft.resolution.getScaledWidthScreenCoords());
-        cursorY = Math.min(cursorY, minecraft.resolution.getScaledHeightScreenCoords());
+        this.cursorX = Math.min(this.cursorX, this.minecraft.resolution.getScaledWidthScreenCoords());
+        this.cursorY = Math.min(this.cursorY, this.minecraft.resolution.getScaledHeightScreenCoords());
     }
 
     public boolean hasAnyInput() {
-        return controller.hasAnyInput();
+        return this.controller.hasAnyInput();
     }
 
     public GlfwGamepad getController() {
-        return controller;
+        return this.controller;
     }
 
     public void update() {
-        if (disconnected || !controller.isPresent()) {
+        if (this.disconnected || !this.controller.isPresent()) {
             this.disconnected = true;
             throw new RuntimeException("Controller Disconnected!");
         }
 
-        for (int i = 0; i < buttons.length; i++) {
-            buttons[i].update();
+        for (int i = 0; i < this.buttons.length; i++) {
+            this.buttons[i].update();
         }
-        for (int i = 0; i < joysticks.length; i++) {
-            joysticks[i].update();
+        for (int i = 0; i < this.joysticks.length; i++) {
+            this.joysticks[i].update();
         }
-        digitalPad.update();
+        this.digitalPad.update();
     }
 
     public Slot getSlotAtCursor(ScreenContainerAbstract screen) {
-        return getSlotAt((int) cursorX, (int) cursorY, screen);
+        return getSlotAt((int) this.cursorX, (int) this.cursorY, screen);
     }
 
     public Slot getSlotAt(int x, int y, ScreenContainerAbstract screen) {
         for (Slot slot : screen.inventorySlots.slots) {
-            int mx = (int) cursorX;
-            int my = (int) cursorY;
+            int mx = (int) this.cursorX;
+            int my = (int) this.cursorY;
 
-            int slotX = (slot.x + (minecraft.resolution.getScaledWidthScreenCoords() - screen.xSize) / 2) - 2;
-            int slotY = (slot.y + (minecraft.resolution.getScaledHeightScreenCoords() - screen.ySize) / 2) - 2;
+            int slotX = (slot.x + (this.minecraft.resolution.getScaledWidthScreenCoords() - screen.xSize) / 2) - 2;
+            int slotY = (slot.y + (this.minecraft.resolution.getScaledHeightScreenCoords() - screen.ySize) / 2) - 2;
 
             if (mx > slotX && my > slotY && mx < slotX + 20 && my < slotY + 20) {
                 return slot;
@@ -175,163 +176,90 @@ public class ControllerInput {
     public void snapToSlot(ScreenContainerAbstract screen, Slot slot) {
         if (slot == null) return;
 
-        int slotX = (slot.x + (minecraft.resolution.getScaledWidthScreenCoords() - screen.xSize) / 2) - 1;
-        int slotY = (slot.y + (minecraft.resolution.getScaledHeightScreenCoords() - screen.ySize) / 2) - 1;
+        int slotX = (slot.x + (this.minecraft.resolution.getScaledWidthScreenCoords() - screen.xSize) / 2) - 1;
+        int slotY = (slot.y + (this.minecraft.resolution.getScaledHeightScreenCoords() - screen.ySize) / 2) - 1;
 
         //Snap to Slot
-        cursorX = slotX + 8;
-        cursorY = slotY + 8;
+        this.cursorX = slotX + 8;
+        this.cursorY = slotY + 8;
     }
 
     public void cancelButtonPresses() {
-        for (Button button : buttons) {
+        for (Button button : this.buttons) {
             button.cancelButtonPress();
         }
     }
 
     private String translateAxis(ControllerType controllerType, int axis) {
-        switch (axis) {
-            case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X:
-            case GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y:
-                return "Analog Left";
-            case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X:
-            case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y:
-                return "Analog Right";
-            case GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER:
-                switch (controllerType) {
-                    case PS3:
-                    case PS4:
-                    case PS5:
-                        return "L2";
-                    case SWITCH:
-                        return "ZL";
-                    default:
-                        return "LT";
-                }
-            case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER:
-                switch (controllerType) {
-                    case PS3:
-                    case PS4:
-                    case PS5:
-                        return "R2";
-                    case SWITCH:
-                        return "ZR";
-                    default:
-                        return "RT";
-                }
-            default:
-                return "Axis " + axis;
-        }
+        return switch (axis) {
+            case GLFW.GLFW_GAMEPAD_AXIS_LEFT_X, GLFW.GLFW_GAMEPAD_AXIS_LEFT_Y -> "Analog Left";
+            case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_X, GLFW.GLFW_GAMEPAD_AXIS_RIGHT_Y -> "Analog Right";
+            case GLFW.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER -> switch (controllerType) {
+                case PS3, PS4, PS5 -> "L2";
+                case SWITCH -> "ZL";
+                default -> "LT";
+            };
+            case GLFW.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER -> switch (controllerType) {
+                case PS3, PS4, PS5 -> "R2";
+                case SWITCH -> "ZR";
+                default -> "RT";
+            };
+            default -> "Axis " + axis;
+        };
     }
 
     private String translateBtn(ControllerType controllerType, int button) {
-        switch (button) {
-            case GLFW.GLFW_GAMEPAD_BUTTON_A:
-                switch (controllerType) {
-                    case PS3:
-                    case PS4:
-                    case PS5:
-                        return "X";
-                    case SWITCH:
-                        return "B";
-                    default:
-                        return "A";
-                }
-            case GLFW.GLFW_GAMEPAD_BUTTON_B:
-                switch (controllerType) {
-                    case PS3:
-                    case PS4:
-                    case PS5:
-                        return "O";
-                    case SWITCH:
-                        return "A";
-                    default:
-                        return "B";
-                }
-            case GLFW.GLFW_GAMEPAD_BUTTON_X:
-                switch (controllerType) {
-                    case PS3:
-                    case PS4:
-                    case PS5:
-                        return "□";
-                    case SWITCH:
-                        return "Y";
-                    default:
-                        return "X";
-                }
-            case GLFW.GLFW_GAMEPAD_BUTTON_Y:
-                switch (controllerType) {
-                    case PS3:
-                    case PS4:
-                    case PS5:
-                        return "△";
-                    case SWITCH:
-                        return "X";
-                    default:
-                        return "Y";
-                }
-            case GLFW.GLFW_GAMEPAD_BUTTON_BACK:
-                switch (controllerType) {
-                    case XBOX_ONE:
-                        return "View";
-                    case PS3:
-                        return "Select";
-                    case PS4:
-                    case PS5:
-                        return "Share";
-                    case SWITCH:
-                        return "-";
-                    default:
-                        return "Back";
-                }
-            case GLFW.GLFW_GAMEPAD_BUTTON_START:
-                switch (controllerType) {
-                    case XBOX_ONE:
-                        return "Menu";
-                    case PS4:
-                    case PS5:
-                        return "Options";
-                    case SWITCH:
-                        return "+";
-                    default:
-                        return "Start";
-                }
-            case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER:
-                switch (controllerType) {
-                    case PS3:
-                    case PS4:
-                    case PS5:
-                        return "L1";
-                    case SWITCH:
-                        return "L";
-                    default:
-                        return "LB";
-                }
-            case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER:
-                switch (controllerType) {
-                    case PS3:
-                    case PS4:
-                    case PS5:
-                        return "R1";
-                    case SWITCH:
-                        return "R";
-                    default:
-                        return "RB";
-                }
-            case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB:
-                return "Left Stick";
-            case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB:
-                return "Right Stick";
-            case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP:
-                return "Digital Up";
-            case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN:
-                return "Digital Down";
-            case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT:
-                return "Digital Left";
-            case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT:
-                return "Digital Right";
-            default:
-                return "Button " + button;
-        }
+        return switch (button) {
+            case GLFW.GLFW_GAMEPAD_BUTTON_A -> switch (controllerType) {
+                case PS3, PS4, PS5 -> "X";
+                case SWITCH -> "B";
+                default -> "A";
+            };
+            case GLFW.GLFW_GAMEPAD_BUTTON_B -> switch (controllerType) {
+                case PS3, PS4, PS5 -> "O";
+                case SWITCH -> "A";
+                default -> "B";
+            };
+            case GLFW.GLFW_GAMEPAD_BUTTON_X -> switch (controllerType) {
+                case PS3, PS4, PS5 -> "□";
+                case SWITCH -> "Y";
+                default -> "X";
+            };
+            case GLFW.GLFW_GAMEPAD_BUTTON_Y -> switch (controllerType) {
+                case PS3, PS4, PS5 -> "△";
+                case SWITCH -> "X";
+                default -> "Y";
+            };
+            case GLFW.GLFW_GAMEPAD_BUTTON_BACK -> switch (controllerType) {
+                case XBOX_ONE -> "View";
+                case PS3 -> "Select";
+                case PS4, PS5 -> "Share";
+                case SWITCH -> "-";
+                default -> "Back";
+            };
+            case GLFW.GLFW_GAMEPAD_BUTTON_START -> switch (controllerType) {
+                case XBOX_ONE -> "Menu";
+                case PS4, PS5 -> "Options";
+                case SWITCH -> "+";
+                default -> "Start";
+            };
+            case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER -> switch (controllerType) {
+                case PS3, PS4, PS5 -> "L1";
+                case SWITCH -> "L";
+                default -> "LB";
+            };
+            case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER -> switch (controllerType) {
+                case PS3, PS4, PS5 -> "R1";
+                case SWITCH -> "R";
+                default -> "RB";
+            };
+            case GLFW.GLFW_GAMEPAD_BUTTON_LEFT_THUMB -> "Left Stick";
+            case GLFW.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB -> "Right Stick";
+            case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_UP -> "Digital Up";
+            case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_DOWN -> "Digital Down";
+            case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_LEFT -> "Digital Left";
+            case GLFW.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT -> "Digital Right";
+            default -> "Button " + button;
+        };
     }
 }
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 892633eaf..8b6e38fc4 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
@@ -18,6 +18,7 @@ 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.Blocks;
 import net.minecraft.core.block.entity.TileEntityActivator;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.block.entity.TileEntityDispatcher;
@@ -64,6 +65,7 @@ import net.minecraft.core.world.ExplosionCannonball;
 import net.minecraft.core.world.ICarriable;
 import net.minecraft.core.world.IVehicle;
 import net.minecraft.core.world.data.SynchedEntityData;
+import net.minecraft.core.world.pos.ChunkPos;
 import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.save.LevelData;
 import net.minecraft.core.world.saveddata.SavedDataStorage;
@@ -79,11 +81,9 @@ import java.io.InputStreamReader;
 import java.net.InetAddress;
 import java.net.Socket;
 import java.net.URL;
-import java.net.UnknownHostException;
 import java.util.*;
 
-public class PacketHandlerClient extends PacketHandler
-{
+public class PacketHandlerClient extends PacketHandler {
     private static final Logger LOGGER = LogUtils.getLogger();
     private boolean disconnected;
     private final NetworkManager netManager;
@@ -97,50 +97,40 @@ public class PacketHandlerClient extends PacketHandler
     Random rand;
 
     public PacketHandlerClient(Minecraft minecraft, String host, int port)
-            throws UnknownHostException, IOException
-    {
-        disconnected = false;
-        started = false;
-        savedDataStorage = new SavedDataStorage(null);
-        rand = new Random();
-        mc = minecraft;
+        throws IOException {
+        this.disconnected = false;
+        this.started = false;
+        this.savedDataStorage = new SavedDataStorage(null);
+        this.rand = new Random();
+        this.mc = minecraft;
         Socket socket = new Socket(InetAddress.getByName(host), port);
-        netManager = new NetworkManager(socket, "Client", this, -1);
-        players = new ArrayList<>();
+        this.netManager = new NetworkManager(socket, "Client", this, -1);
+        this.players = new ArrayList<>();
     }
 
-    public void tick()
-    {
-        if (!disconnected)
-        {
-            netManager.processReadPackets();
+    public void tick() {
+        if (!this.disconnected) {
+            this.netManager.processReadPackets();
         }
-        netManager.wakeThreads();
+        this.netManager.wakeThreads();
     }
 
-    public int findPlayerInList(PlayerProfile playerProfile)
-    {
-        for (int i = 0; i < players.size(); i++)
-        {
-            if (players.get(i).playerName.equals(playerProfile.playerName))
-            {
+    public int findPlayerInList(@NotNull PlayerProfile playerProfile) {
+        for (int i = 0; i < this.players.size(); i++) {
+            if (this.players.get(i).playerName.equals(playerProfile.playerName)) {
                 return i;
             }
         }
         return -1;
     }
 
-    public void addPlayer(PlayerProfile playerProfile)
-    {
-        players.add(playerProfile);
+    public void addPlayer(@NotNull PlayerProfile playerProfile) {
+        this.players.add(playerProfile);
     }
 
-    public PlayerProfile getPlayer(String username)
-    {
-        for (PlayerProfile player : players)
-        {
-            if (player.playerName.equals(username))
-            {
+    public @Nullable PlayerProfile getPlayer(@NotNull String username) {
+        for (PlayerProfile player : this.players) {
+            if (player.playerName.equals(username)) {
                 return player;
             }
         }
@@ -148,32 +138,30 @@ public class PacketHandlerClient extends PacketHandler
         return null;
     }
 
-    public void removePlayer(int index)
-    {
-        players.remove(index);
+    public void removePlayer(int index) {
+        this.players.remove(index);
     }
 
 
     @Override
-    public void handleLogin(@NotNull PacketLogin packetLogin)
-    {
-        mc.playerController = new PlayerControllerMP(mc, this);
-        mc.statsCounter.add(StatList.joinMultiplayerStat, 1);
-        worldClientMP = new WorldClientMP(this, packetLogin.worldSeed, packetLogin.dimensionId, packetLogin.worldTypeId);
-        worldClientMP.isClientSide = true;
-        mc.changeWorld(worldClientMP);
-        mc.thePlayer.dimension = packetLogin.dimensionId;
-        mc.displayScreen(new ScreenDownloadTerrain(this));
-        mc.thePlayer.id = packetLogin.playerEntityIdAndProtocolVersion;
+    public void handleLogin(@NotNull PacketLogin packetLogin) {
+        this.mc.playerController = new PlayerControllerMP(this.mc, this);
+        this.mc.statsCounter.add(StatList.joinMultiplayerStat, 1);
+        this.worldClientMP = new WorldClientMP(this, packetLogin.worldSeed, packetLogin.dimensionId, packetLogin.worldTypeId);
+        this.worldClientMP.isClientSide = true;
+        this.mc.changeWorld(this.worldClientMP);
+        this.mc.thePlayer.dimension = packetLogin.dimensionId;
+        this.mc.displayScreen(new ScreenDownloadTerrain(this));
+        this.mc.thePlayer.id = packetLogin.playerEntityIdAndProtocolVersion;
         NetworkManager.PACKET_DELAY = packetLogin.packetDelay;
         Registries.RECIPES = new RecipeRegistry();
 
-        addToSendQueue(new PacketPlayerConfig(mc.thePlayer.playerConfig));
+        addToSendQueue(new PacketPlayerConfig(this.mc.thePlayer.playerConfig));
     }
 
     @Override
     public void handlePlayerConfig(@NotNull PacketPlayerConfig packetPlayerConfig) {
-        if (packetPlayerConfig.entityId >= 0 && packetPlayerConfig.entityId != mc.thePlayer.id) {
+        if (packetPlayerConfig.entityId >= 0 && packetPlayerConfig.entityId != this.mc.thePlayer.id) {
             Entity e = getEntityByID(packetPlayerConfig.entityId);
             if (e instanceof Player) {
                 ((Player) e).playerConfig.config = packetPlayerConfig.config;
@@ -182,35 +170,36 @@ public class PacketHandlerClient extends PacketHandler
     }
 
     @Override
-    public void handleAddItemEntity(@NotNull PacketAddItemEntity packetAddItemEntity)
-    {
+    public void handleAddItemEntity(@NotNull PacketAddItemEntity packetAddItemEntity) {
         double x = packetAddItemEntity.xPosition / 32D;
         double y = packetAddItemEntity.yPosition / 32D;
         double z = packetAddItemEntity.zPosition / 32D;
-        EntityItem entityItem = new EntityItem(worldClientMP, x, y, z, new ItemStack(packetAddItemEntity.itemID, packetAddItemEntity.count, packetAddItemEntity.itemDamage, packetAddItemEntity.tag));
+        EntityItem entityItem = new EntityItem(this.worldClientMP, x, y, z, new ItemStack(packetAddItemEntity.itemID, packetAddItemEntity.count, packetAddItemEntity.itemDamage, packetAddItemEntity.tag));
         entityItem.xd = (double) packetAddItemEntity.xd / 128D;
         entityItem.yd = (double) packetAddItemEntity.yd / 128D;
         entityItem.zd = (double) packetAddItemEntity.zd / 128D;
         entityItem.serverPosX = packetAddItemEntity.xPosition;
         entityItem.serverPosY = packetAddItemEntity.yPosition;
         entityItem.serverPosZ = packetAddItemEntity.zPosition;
-        worldClientMP.addEntityToWorld(packetAddItemEntity.entityId, entityItem);
+        this.worldClientMP.addEntityToWorld(packetAddItemEntity.entityId, entityItem);
     }
 
 
     @Override
     public void handleAddEntity(@NotNull PacketAddEntity packetAddEntity) {
-        if (!NetEntityHandler.hasType(packetAddEntity.type)){ return; }
+        if (!NetEntityHandler.hasType(packetAddEntity.type)) {
+            return;
+        }
         double xPosition = ((double) packetAddEntity.xPosition) / 32D;
         double yPosition = ((double) packetAddEntity.yPosition) / 32D;
         double zPosition = ((double) packetAddEntity.zPosition) / 32D;
         Entity owner;
-        if (packetAddEntity.ownerId >= 0){
+        if (packetAddEntity.ownerId >= 0) {
             owner = getEntityByID(packetAddEntity.ownerId);
         } else {
             owner = null;
         }
-        Entity newEntity = NetEntityHandler.getTypeEntry(packetAddEntity.type).getEntity(worldClientMP, xPosition, yPosition, zPosition, packetAddEntity.metaData, packetAddEntity.hasVelocity, packetAddEntity.xVelocity / 8000D, packetAddEntity.yVelocity / 8000D, packetAddEntity.zVelocity / 8000D, owner, packetAddEntity.tag);
+        Entity newEntity = NetEntityHandler.getTypeEntry(packetAddEntity.type).getEntity(this.worldClientMP, xPosition, yPosition, zPosition, packetAddEntity.metaData, packetAddEntity.hasVelocity, packetAddEntity.xVelocity / 8000D, packetAddEntity.yVelocity / 8000D, packetAddEntity.zVelocity / 8000D, owner, packetAddEntity.tag);
         if (newEntity != null) {
             newEntity.serverPosX = packetAddEntity.xPosition;
             newEntity.serverPosY = packetAddEntity.yPosition;
@@ -218,58 +207,52 @@ public class PacketHandlerClient extends PacketHandler
             newEntity.yRot = packetAddEntity.yaw;
             newEntity.xRot = packetAddEntity.pitch;
             newEntity.id = packetAddEntity.entityId;
-            worldClientMP.addEntityToWorld(packetAddEntity.entityId, newEntity);
-            if (owner instanceof Mob && newEntity instanceof Projectile){
+            this.worldClientMP.addEntityToWorld(packetAddEntity.entityId, newEntity);
+            if (owner instanceof Mob && newEntity instanceof Projectile) {
                 ((Projectile) newEntity).owner = (Mob) owner;
             }
-            if (packetAddEntity.hasVelocity){
+            if (packetAddEntity.hasVelocity) {
                 newEntity.lerpMotion(((double) packetAddEntity.xVelocity) / 8000D, ((double) packetAddEntity.yVelocity) / 8000D, ((double) packetAddEntity.zVelocity) / 8000D);
             }
             List<SynchedEntityData.DataItem<?>> list = packetAddEntity.getUnpackedData();
-            if (list != null)
-            {
+            if (list != null) {
                 newEntity.getEntityData().assignValues(list);
             }
         }
     }
 
     @Override
-    public void handleWeatherEffect(@NotNull PacketWeatherEffect packetWeatherEffect)
-    {
+    public void handleWeatherEffect(@NotNull PacketWeatherEffect packetWeatherEffect) {
         double x = (double) packetWeatherEffect.x / 32D;
         double y = (double) packetWeatherEffect.y / 32D;
         double z = (double) packetWeatherEffect.z / 32D;
         Entity weatherEntity = null;
         if (packetWeatherEffect.effectId == PacketWeatherEffect.EFFECT_LIGHTNING) {
-            weatherEntity = new EntityLightning(worldClientMP, x, y, z);
+            weatherEntity = new EntityLightning(this.worldClientMP, x, y, z);
         }
-        if (weatherEntity != null)
-        {
+        if (weatherEntity != null) {
             weatherEntity.serverPosX = packetWeatherEffect.x;
             weatherEntity.serverPosY = packetWeatherEffect.y;
             weatherEntity.serverPosZ = packetWeatherEffect.z;
             weatherEntity.yRot = 0.0F;
             weatherEntity.xRot = 0.0F;
             weatherEntity.id = packetWeatherEffect.id;
-            worldClientMP.addWeatherEffect(weatherEntity);
+            this.worldClientMP.addWeatherEffect(weatherEntity);
         }
     }
 
     @Override
-    public void handleWeatherStatus(@NotNull PacketWeatherStatus packet)
-    {
-        if (worldClientMP.dimension.id != packet.dimId) return;
+    public void handleWeatherStatus(@NotNull PacketWeatherStatus packet) {
+        if (this.worldClientMP.dimension.id != packet.dimId) return;
         Weather currentWeather = packet.id == -1 ? null : Weathers.WEATHERS[packet.id];
         Weather newWeather = packet.newId == -1 ? null : Weathers.WEATHERS[packet.newId];
-        worldClientMP.weatherManager.overrideWeather(currentWeather, newWeather, packet.duration, packet.intensity, packet.power);
+        this.worldClientMP.weatherManager.overrideWeather(currentWeather, newWeather, packet.duration, packet.intensity, packet.power);
     }
 
     @Override
-    public void handleAddPainting(@NotNull PacketAddPainting packetAddPainting)
-    {
-        Entity entity = worldClientMP.getEntityFromId(packetAddPainting.entityId);
-        if (entity instanceof EntityPainting){
-            EntityPainting painting = (EntityPainting) entity;
+    public void handleAddPainting(@NotNull PacketAddPainting packetAddPainting) {
+        Entity entity = this.worldClientMP.getEntityFromId(packetAddPainting.entityId);
+        if (entity instanceof EntityPainting painting) {
             painting.blockX = packetAddPainting.xPosition;
             painting.blockY = packetAddPainting.yPosition;
             painting.blockZ = packetAddPainting.zPosition;
@@ -277,13 +260,13 @@ public class PacketHandlerClient extends PacketHandler
             if (ArtType.map.containsKey(packetAddPainting.key)) painting.art = ArtType.map.get(packetAddPainting.key);
 
             painting.setDirection(packetAddPainting.direction);
-            if (packetAddPainting.itemID > 0){
+            if (packetAddPainting.itemID > 0) {
                 painting.setStack(new ItemStack(packetAddPainting.itemID, 1, packetAddPainting.meta));
             }
         } else {
-            EntityPainting entitypainting = new EntityPainting(worldClientMP, packetAddPainting.xPosition, packetAddPainting.yPosition, packetAddPainting.zPosition, packetAddPainting.direction, packetAddPainting.key);
-            worldClientMP.addEntityToWorld(packetAddPainting.entityId, entitypainting);
-            if (packetAddPainting.itemID > 0){
+            EntityPainting entitypainting = new EntityPainting(this.worldClientMP, packetAddPainting.xPosition, packetAddPainting.yPosition, packetAddPainting.zPosition, packetAddPainting.direction, packetAddPainting.key);
+            this.worldClientMP.addEntityToWorld(packetAddPainting.entityId, entitypainting);
+            if (packetAddPainting.itemID > 0) {
                 entitypainting.setStack(new ItemStack(packetAddPainting.itemID, 1, packetAddPainting.meta));
             }
         }
@@ -291,8 +274,7 @@ public class PacketHandlerClient extends PacketHandler
     }
 
     @Override
-    public void handleSetEntityMotion(@NotNull PacketSetEntityMotion packetSetEntityMotion)
-    {
+    public void handleSetEntityMotion(@NotNull PacketSetEntityMotion packetSetEntityMotion) {
         Entity entity = getEntityByID(packetSetEntityMotion.entityId);
         if (entity != null) {
             entity.lerpMotion((double) packetSetEntityMotion.motionX / 8000D, (double) packetSetEntityMotion.motionY / 8000D, (double) packetSetEntityMotion.motionZ / 8000D);
@@ -313,18 +295,15 @@ public class PacketHandlerClient extends PacketHandler
     }
 
     @Override
-    public void handleSetEntityData(@NotNull PacketSetEntityData packetSetEntityData)
-    {
+    public void handleSetEntityData(@NotNull PacketSetEntityData packetSetEntityData) {
         Entity entity = getEntityByID(packetSetEntityData.entityId);
-        if (entity != null && packetSetEntityData.getUnpackedData() != null)
-        {
+        if (entity != null && packetSetEntityData.getUnpackedData() != null) {
             entity.getEntityData().assignValues(packetSetEntityData.getUnpackedData());
         }
     }
 
     @Override
-    public void handleAddPlayer(final @NotNull PacketAddPlayer packetAddPlayer)
-    {
+    public void handleAddPlayer(final @NotNull PacketAddPlayer packetAddPlayer) {
         final double x = (double) packetAddPlayer.xPosition / 32D;
         final double y = (double) packetAddPlayer.yPosition / 32D;
         final double z = (double) packetAddPlayer.zPosition / 32D;
@@ -337,12 +316,9 @@ public class PacketHandlerClient extends PacketHandler
         playerRemote.yo = playerRemote.serverPosY = packetAddPlayer.yPosition;
         playerRemote.zo = playerRemote.serverPosZ = packetAddPlayer.zPosition;
         final int itemId = packetAddPlayer.currentItem;
-        if (itemId == 0)
-        {
+        if (itemId == 0) {
             playerRemote.inventory.mainInventory[playerRemote.inventory.getCurrentSlot()] = null;
-        }
-        else
-        {
+        } else {
             playerRemote.inventory.mainInventory[playerRemote.inventory.getCurrentSlot()] = new ItemStack(itemId, 1, 0);
         }
         playerRemote.absMoveTo(x, y, z, yRot, xRot);
@@ -355,8 +331,7 @@ public class PacketHandlerClient extends PacketHandler
     }
 
     @Override
-    public void handleTeleportEntity(@NotNull PacketTeleportEntity packetTeleportEntity)
-    {
+    public void handleTeleportEntity(@NotNull PacketTeleportEntity packetTeleportEntity) {
         Entity entity = getEntityByID(packetTeleportEntity.id);
         if (entity != null) {
             entity.serverPosX = packetTeleportEntity.x;
@@ -372,8 +347,7 @@ public class PacketHandlerClient extends PacketHandler
     }
 
     @Override
-    public void handleMoveEntity(@NotNull PacketMoveEntity packetMoveEntity)
-    {
+    public void handleMoveEntity(@NotNull PacketMoveEntity packetMoveEntity) {
         Entity entity = getEntityByID(packetMoveEntity.id);
         if (entity != null) {
             entity.serverPosX += packetMoveEntity.x;
@@ -407,351 +381,295 @@ public class PacketHandlerClient extends PacketHandler
             }
         }
     }
+
     @Override
-    public void handleSetHotbarOffset(@NotNull PacketSetHotbarOffset packetSetHotbarOffset)
-    {
-        mc.thePlayer.inventory.setHotbarOffset(packetSetHotbarOffset.hotbarOffset, true);
+    public void handleSetHotbarOffset(@NotNull PacketSetHotbarOffset packetSetHotbarOffset) {
+        this.mc.thePlayer.inventory.setHotbarOffset(packetSetHotbarOffset.hotbarOffset, true);
     }
 
     @Override
-    public void handleRemoveEntity(@NotNull PacketRemoveEntity packetRemoveEntity)
-    {
-        worldClientMP.removeEntityFromWorld(packetRemoveEntity.entityId);
+    public void handleRemoveEntity(@NotNull PacketRemoveEntity packetRemoveEntity) {
+        this.worldClientMP.removeEntityFromWorld(packetRemoveEntity.entityId);
     }
 
     @Override
-    public void handleMovePlayer(@NotNull PacketMovePlayer packetMovePlayer)
-    {
-        PlayerLocal entityplayersp = mc.thePlayer;
-        double d = ((Player) (entityplayersp)).x;
-        double d1 = ((Player) (entityplayersp)).y;
-        double d2 = ((Player) (entityplayersp)).z;
-        float f = ((Player) (entityplayersp)).yRot;
-        float f1 = ((Player) (entityplayersp)).xRot;
-        if (packetMovePlayer.hasPosition)
-        {
+    public void handleMovePlayer(@NotNull PacketMovePlayer packetMovePlayer) {
+        PlayerLocal entityplayersp = this.mc.thePlayer;
+        double d = entityplayersp.x;
+        double d1 = entityplayersp.y;
+        double d2 = entityplayersp.z;
+        float f = entityplayersp.yRot;
+        float f1 = entityplayersp.xRot;
+        if (packetMovePlayer.hasPosition) {
             d = packetMovePlayer.x;
             d1 = packetMovePlayer.y;
             d2 = packetMovePlayer.z;
         }
-        if (packetMovePlayer.hasRotation)
-        {
+        if (packetMovePlayer.hasRotation) {
             f = packetMovePlayer.yaw;
             f1 = packetMovePlayer.pitch;
         }
         entityplayersp.ySlideOffset = 0.0F;
         entityplayersp.xd = entityplayersp.yd = entityplayersp.zd = 0.0D;
         entityplayersp.absMoveTo(d, d1, d2, f, f1);
-        packetMovePlayer.x = ((Player) (entityplayersp)).x;
-        packetMovePlayer.y = ((Player) (entityplayersp)).bb.minY;
-        packetMovePlayer.z = ((Player) (entityplayersp)).z;
-        netManager.addToSendQueue(packetMovePlayer);
-        if (!started)
-        {
-            mc.thePlayer.xo = mc.thePlayer.x;
-            mc.thePlayer.yo = mc.thePlayer.y;
-            mc.thePlayer.zo = mc.thePlayer.z;
-            started = true;
-            mc.displayScreen(null);
+        packetMovePlayer.x = entityplayersp.x;
+        packetMovePlayer.y = entityplayersp.bb.minY;
+        packetMovePlayer.z = entityplayersp.z;
+        this.netManager.addToSendQueue(packetMovePlayer);
+        if (!this.started) {
+            this.mc.thePlayer.xo = this.mc.thePlayer.x;
+            this.mc.thePlayer.yo = this.mc.thePlayer.y;
+            this.mc.thePlayer.zo = this.mc.thePlayer.z;
+            this.started = true;
+            this.mc.displayScreen(null);
         }
     }
 
     @Override
-    public void handleChunkVisibility(@NotNull PacketChunkVisibility packetChunkVisibility)
-    {
-        worldClientMP.doPreChunk(packetChunkVisibility.chunkX, packetChunkVisibility.chunkZ, packetChunkVisibility.playerAdded);
+    public void handleChunkVisibility(@NotNull PacketChunkVisibility packetChunkVisibility) {
+        this.worldClientMP.doPreChunk(new ChunkPos(packetChunkVisibility.chunkX, packetChunkVisibility.chunkZ), packetChunkVisibility.playerAdded);
     }
 
     @Override
-    public void handleChunkBlocksUpdate(@NotNull PacketChunkBlocksUpdate packetChunkBlocksUpdate)
-    {
+    public void handleChunkBlocksUpdate(@NotNull PacketChunkBlocksUpdate packetChunkBlocksUpdate) {
         int xBase = packetChunkBlocksUpdate.xChunk * 16;
         int zBase = packetChunkBlocksUpdate.zChunk * 16;
-        for (int k = 0; k < packetChunkBlocksUpdate.size; k++)
-        {
+        for (int k = 0; k < packetChunkBlocksUpdate.size; k++) {
             int coord = packetChunkBlocksUpdate.coordinateArray[k];
             int type = packetChunkBlocksUpdate.typeArray[k] & 0x3fff;
             byte data = packetChunkBlocksUpdate.metadataArray[k];
             int x = coord >> 0 & 0xf;
             int y = coord >> 8 & 0xff;
             int z = coord >> 4 & 0xf;
-            worldClientMP.setBlockAndMetadataWithNotify(x + xBase, y, z + zBase, type, data);
-            worldClientMP.removePositionTypesInBounds(x + xBase, y, z + zBase, x + xBase, y, z + zBase);
-            worldClientMP.markBlocksDirty(x + xBase, y, z + zBase, x + xBase, y, z + zBase);
+            this.worldClientMP.setBlockAndMetadataWithNotify(x + xBase, y, z + zBase, type, data);
+            this.worldClientMP.removePositionTypesInBounds(new TilePos(x + xBase, y, z + zBase), new TilePos(x + xBase, y, z + zBase));
+            this.worldClientMP.markBlocksDirty(x + xBase, y, z + zBase, x + xBase, y, z + zBase);
         }
 
     }
 
     @Override
-    public void handleBlockRegionUpdate(@NotNull PacketBlockRegionUpdate packetBlockRegionUpdate)
-    {
-        for (int x = packetBlockRegionUpdate.xPosition / 16; x <= packetBlockRegionUpdate.xPosition / 16 + packetBlockRegionUpdate.xSize / 16; x++) {
-            for (int z = packetBlockRegionUpdate.zPosition / 16; z <= packetBlockRegionUpdate.zPosition / 16 + packetBlockRegionUpdate.zSize / 16; z++) {
-                worldClientMP.doPreChunk(x, z, true);
+    public void handleBlockRegionUpdate(@NotNull PacketBlockRegionUpdate packetBlockRegionUpdate) {
+        ChunkPos pos = new ChunkPos();
+        for (pos.x = packetBlockRegionUpdate.xPosition / 16; pos.x <= packetBlockRegionUpdate.xPosition / 16 + packetBlockRegionUpdate.xSize / 16; pos.x++) {
+            for (pos.z = packetBlockRegionUpdate.zPosition / 16; pos.z <= packetBlockRegionUpdate.zPosition / 16 + packetBlockRegionUpdate.zSize / 16; pos.z++) {
+                this.worldClientMP.doPreChunk(pos, true);
             }
         }
-        worldClientMP.removePositionTypesInBounds(packetBlockRegionUpdate.xPosition, packetBlockRegionUpdate.yPosition, packetBlockRegionUpdate.zPosition, (packetBlockRegionUpdate.xPosition + packetBlockRegionUpdate.xSize) - 1, (packetBlockRegionUpdate.yPosition + packetBlockRegionUpdate.ySize) - 1, (packetBlockRegionUpdate.zPosition + packetBlockRegionUpdate.zSize) - 1);
-        worldClientMP.setChunkData(packetBlockRegionUpdate.xPosition, packetBlockRegionUpdate.yPosition, packetBlockRegionUpdate.zPosition, packetBlockRegionUpdate.xSize, packetBlockRegionUpdate.ySize, packetBlockRegionUpdate.zSize, packetBlockRegionUpdate.chunk);
+        this.worldClientMP.removePositionTypesInBounds(new TilePos(packetBlockRegionUpdate.xPosition, packetBlockRegionUpdate.yPosition, packetBlockRegionUpdate.zPosition), new TilePos((packetBlockRegionUpdate.xPosition + packetBlockRegionUpdate.xSize) - 1, (packetBlockRegionUpdate.yPosition + packetBlockRegionUpdate.ySize) - 1, (packetBlockRegionUpdate.zPosition + packetBlockRegionUpdate.zSize) - 1));
+        this.worldClientMP.setChunkData(packetBlockRegionUpdate.xPosition, packetBlockRegionUpdate.yPosition, packetBlockRegionUpdate.zPosition, packetBlockRegionUpdate.xSize, packetBlockRegionUpdate.ySize, packetBlockRegionUpdate.zSize, packetBlockRegionUpdate.chunk);
     }
 
     @Override
-    public void handleBlockUpdate(@NotNull PacketBlockUpdate packetBlockUpdate)
-    {
-        worldClientMP.blockChange(packetBlockUpdate.xPosition, packetBlockUpdate.yPosition, packetBlockUpdate.zPosition, packetBlockUpdate.blockId, packetBlockUpdate.metadata);
+    public void handleBlockUpdate(@NotNull PacketBlockUpdate packetBlockUpdate) {
+        this.worldClientMP.blockChange(new TilePos(packetBlockUpdate.xPosition, packetBlockUpdate.yPosition, packetBlockUpdate.zPosition), Blocks.getBlock(packetBlockUpdate.blockId), packetBlockUpdate.metadata);
     }
 
     @Override
-    public void handleDisconnect(@NotNull PacketDisconnect packetDisconnect)
-    {
-        netManager.networkShutdown("disconnect.kicked", new Object[0]);
-        disconnected = true;
-        mc.changeWorld(null);
-        mc.displayScreen(new ScreenConnectFailed("disconnect.disconnected", "disconnect.genericReason", new Object[]{
+    public void handleDisconnect(@NotNull PacketDisconnect packetDisconnect) {
+        this.netManager.networkShutdown("disconnect.kicked", new Object[0]);
+        this.disconnected = true;
+        this.mc.changeWorld(null);
+        this.mc.displayScreen(new ScreenConnectFailed("disconnect.disconnected", "disconnect.genericReason", new Object[]{
             packetDisconnect.reason
         }));
     }
 
     @Override
-    public void handleErrorMessage(String message, Object[] objects)
-    {
-        if (!disconnected) {
-            disconnected = true;
+    public void handleErrorMessage(String message, Object[] objects) {
+        if (!this.disconnected) {
+            this.disconnected = true;
             try {
-                mc.changeWorld(null); // Leave current world
+                this.mc.changeWorld(null); // Leave current world
             } catch (Exception e) {
                 LOGGER.error("Exception when leaving world!", e);
             }
             try {
-                mc.displayScreen(null); // Exit out of current GUI
+                this.mc.displayScreen(null); // Exit out of current GUI
             } catch (Exception e) {
                 LOGGER.error("Exception when leaving GUI!", e);
             }
 
-            mc.displayScreen(new ScreenConnectFailed("disconnect.lost", message, objects)); // Open error message gui
+            this.mc.displayScreen(new ScreenConnectFailed("disconnect.lost", message, objects)); // Open error message gui
         }
     }
 
-    public void sendFinalPacket(Packet packet)
-    {
-        if (!disconnected) {
-            netManager.addToSendQueue(packet);
-            netManager.serverShutdown();
+    public void sendFinalPacket(Packet packet) {
+        if (!this.disconnected) {
+            this.netManager.addToSendQueue(packet);
+            this.netManager.serverShutdown();
         }
     }
 
-    public void addToSendQueue(Packet packet)
-    {
-        if (!disconnected) {
-            netManager.addToSendQueue(packet);
+    public void addToSendQueue(Packet packet) {
+        if (!this.disconnected) {
+            this.netManager.addToSendQueue(packet);
         }
     }
 
     @Override
-    public void handleTakeItemEntity(@NotNull PacketTakeItemEntity packetTakeItemEntity)
-    {
+    public void handleTakeItemEntity(@NotNull PacketTakeItemEntity packetTakeItemEntity) {
         Entity item = getEntityByID(packetTakeItemEntity.collectedEntityId);
         Entity collector = getEntityByID(packetTakeItemEntity.collectorEntityId);
-        if (collector == null)
-        {
-            collector = mc.thePlayer;
+        if (collector == null) {
+            collector = this.mc.thePlayer;
         }
-        if (item != null)
-        {
+        if (item != null) {
             // this class does not seem to handle pick up from server dropped items. find where it is.
             // something about that isn't working on servers if the player changed their gamemode.
-            worldClientMP.playSoundAtEntity(null, item, "item.pickup", 1F, ((rand.nextFloat() - rand.nextFloat()) * 0.7F + 1.0F) * 4.0F);
-            mc.particleEngine.add(new ParticlePickupAnimation(mc.currentWorld, item, collector, -0.5F));
-            worldClientMP.removeEntityFromWorld(packetTakeItemEntity.collectedEntityId);
-        }
-    }
-
-	@Override
-	public void handleChat(@NotNull PacketChat packet) {
-		String message;
-		if(packet.encrypted) {
-			try {
-				message = AES.decrypt(packet.message, AES.clientKeyChain);
-			}catch (Exception e) {
-				throw new RuntimeException(PacketChat.ENCRYPTION_ERROR_MESSAGE, e);
-			}
-		}else {
-			message = packet.message;
-		}
-		
-		int type = packet.type;
-		if(type == 1) {
-			mc.hudIngame.heldItemTooltipElement.setString(message);
-		}else {
-			mc.hudIngame.addChatMessage(message);
-		}
-	}
-
-    public void handlePlayerJoin(PacketChat chatPacket)
-    {
-        mc.hudIngame.addChatMessage(chatPacket.message);
-    }
-
-    public void handlePlayerLeave(PacketChat chatPacket)
-    {
-        mc.hudIngame.addChatMessage(chatPacket.message);
-    }
-
-    @Override
-    public void handleAnimation(@NotNull PacketAnimate packetAnimate)
-    {
+            this.worldClientMP.playSoundAtEntity(null, item, "item.pickup", 1F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 4.0F);
+            this.mc.particleEngine.add(new ParticlePickupAnimation(this.mc.currentWorld, item, collector, -0.5F));
+            this.worldClientMP.removeEntityFromWorld(packetTakeItemEntity.collectedEntityId);
+        }
+    }
+
+    @Override
+    public void handleChat(@NotNull PacketChat packet) {
+        String message;
+        if (packet.encrypted) {
+            try {
+                message = AES.decrypt(packet.message, AES.clientKeyChain);
+            } catch (Exception e) {
+                throw new RuntimeException(PacketChat.ENCRYPTION_ERROR_MESSAGE, e);
+            }
+        } else {
+            message = packet.message;
+        }
+
+        int type = packet.type;
+        if (type == 1) {
+            this.mc.hudIngame.heldItemTooltipElement.setString(message);
+        } else {
+            this.mc.hudIngame.addChatMessage(message);
+        }
+    }
+
+    public void handlePlayerJoin(PacketChat chatPacket) {
+        this.mc.hudIngame.addChatMessage(chatPacket.message);
+    }
+
+    public void handlePlayerLeave(PacketChat chatPacket) {
+        this.mc.hudIngame.addChatMessage(chatPacket.message);
+    }
+
+    @Override
+    public void handleAnimation(@NotNull PacketAnimate packetAnimate) {
         Entity entity = getEntityByID(packetAnimate.entityId);
-        if (entity == null)
-        {
+        if (entity == null) {
             return;
         }
-        if (packetAnimate.animate == 1)
-        {
+        if (packetAnimate.animate == 1) {
             Player entityplayer = (Player) entity;
             entityplayer.swingItem();
-        }
-        else if (packetAnimate.animate == 2)
-        {
+        } else if (packetAnimate.animate == 2) {
             entity.animateHurt();
-        }
-        else if (packetAnimate.animate == 3)
-        {
+        } else if (packetAnimate.animate == 3) {
             Player player = (Player) entity;
             player.wakeUpPlayer(false, false);
-        }
-        else if (packetAnimate.animate == 4)
-        {
+        } else if (packetAnimate.animate == 4) {
             Player player = (Player) entity;
             player.animate4();
         }
     }
 
     @Override
-    public void handleBoatControl(@NotNull PacketBoatControl packetBoatControl)
-    {
-        Entity e = worldClientMP.getEntityFromId(packetBoatControl.entityId);
+    public void handleBoatControl(@NotNull PacketBoatControl packetBoatControl) {
+        Entity e = this.worldClientMP.getEntityFromId(packetBoatControl.entityId);
         if (e instanceof EntityBoat) {
-            ((EntityBoat)e).handleControlDirect(packetBoatControl.targetXD, packetBoatControl.targetZD, packetBoatControl.targetYRot);
+            ((EntityBoat) e).handleControlDirect(packetBoatControl.targetXD, packetBoatControl.targetZD, packetBoatControl.targetYRot);
         }
     }
 
     @Override
-    public void handleSleep(@NotNull PacketSleep packetSleep)
-    {
+    public void handleSleep(@NotNull PacketSleep packetSleep) {
         Entity entity = getEntityByID(packetSleep.entityID);
-        if (entity == null)
-        {
+        if (entity == null) {
             return;
         }
-        if (packetSleep.field_22046_e == 0)
-        {
+        if (packetSleep.field_22046_e == 0) {
             Player entityplayer = (Player) entity;
             entityplayer.sleepInBedAt(packetSleep.x, packetSleep.y, packetSleep.z);
         }
     }
 
     @Override
-    public void handleHandshake(@NotNull PacketHandshake packetHandshake)
-    {
-        if (packetHandshake.username.equals("-"))
-        {
-            try
-            {
+    public void handleHandshake(@NotNull PacketHandshake packetHandshake) {
+        if (packetHandshake.username.equals("-")) {
+            try {
                 RSA.RSAKeyChain = RSA.generateKeyPair();
-                addToSendQueue(new PacketLogin(mc.session.username, mc.session.uuid, Global.MP_PROTOCOL_VERSION, RSA.getPublicKey(RSA.RSAKeyChain.getPublic())));
-            }
-            catch (Exception e)
-            {
+                addToSendQueue(new PacketLogin(this.mc.session.username, this.mc.session.uuid, Global.MP_PROTOCOL_VERSION, RSA.getPublicKey(RSA.RSAKeyChain.getPublic())));
+            } catch (Exception e) {
                 throw new RuntimeException(e);
             }
-        }
-        else
-        {
-            try
-            {
-                URL url = new URL("http://session.minecraft.net/game/joinserver.jsp?user=" + mc.session.username + "&sessionId=" + mc.session.sessionId + "&serverId=" + packetHandshake.username);
+        } else {
+            try {
+                URL url = new URL("http://session.minecraft.net/game/joinserver.jsp?user=" + this.mc.session.username + "&sessionId=" + this.mc.session.sessionId + "&serverId=" + packetHandshake.username);
                 BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(url.openStream()));
                 String s = bufferedreader.readLine();
                 bufferedreader.close();
-                if (s.equalsIgnoreCase("ok"))
-                {
-                    try
-                    {
+                if (s.equalsIgnoreCase("ok")) {
+                    try {
                         RSA.RSAKeyChain = RSA.generateKeyPair();
-                        addToSendQueue(new PacketLogin(mc.session.username, mc.session.uuid, Global.MP_PROTOCOL_VERSION, RSA.getPublicKey(RSA.RSAKeyChain.getPublic())));
-                    }
-                    catch (Exception e)
-                    {
+                        addToSendQueue(new PacketLogin(this.mc.session.username, this.mc.session.uuid, Global.MP_PROTOCOL_VERSION, RSA.getPublicKey(RSA.RSAKeyChain.getPublic())));
+                    } catch (Exception e) {
                         throw new RuntimeException("Exception while creating LoginPacket!", e);
                     }
-                }
-                else
-                {
-                    netManager.networkShutdown("disconnect.loginFailedInfo", new Object[]{
-                            s
+                } else {
+                    this.netManager.networkShutdown("disconnect.loginFailedInfo", new Object[]{
+                        s
                     });
                 }
-            }
-            catch (Exception exception)
-            {
+            } catch (Exception exception) {
                 LOGGER.error("Login Exception!", exception);
-                netManager.networkShutdown("disconnect.genericReason", new Object[]{
-                        "Internal client error: " + exception
+                this.netManager.networkShutdown("disconnect.genericReason", new Object[]{
+                    "Internal client error: " + exception
                 });
             }
         }
     }
 
     @Override
-    public void handleAESSendKey(@NotNull PacketAESSendKey packetAESSendKey)
-    {
-        try
-        {
+    public void handleAESSendKey(@NotNull PacketAESSendKey packetAESSendKey) {
+        try {
             AES.clientKeyChain = AES.getKey(RSA.decrypt(packetAESSendKey.KEY, RSA.RSAKeyChain.getPrivate()));
-        }
-        catch (Exception e)
-        {
+        } catch (Exception e) {
             throw new RuntimeException("Failed to get AES key!", e);
         }
     }
 
     @Override
-    public void handlePlayerList(@NotNull PacketPlayerList packetPlayerList)
-    {
-        playerList.clear();
+    public void handlePlayerList(@NotNull PacketPlayerList packetPlayerList) {
+        this.playerList.clear();
         String[] players = packetPlayerList.players;
         String[] scores = packetPlayerList.scores;
-        for (int i = 0; i < players.length; i++)
-        {
-            playerList.put(players[i], scores[i]);
+        for (int i = 0; i < players.length; i++) {
+            this.playerList.put(players[i], scores[i]);
         }
     }
 
-    public void disconnect()
-    {
-        disconnected = true;
-        netManager.wakeThreads();
-        netManager.networkShutdown("disconnect.closed", new Object[0]);
+    public void disconnect() {
+        this.disconnected = true;
+        this.netManager.wakeThreads();
+        this.netManager.networkShutdown("disconnect.closed", new Object[0]);
     }
 
     @Override
-    public void handleAddMob(@NotNull PacketAddMob packetAddMob)
-    {
+    public void handleAddMob(@NotNull PacketAddMob packetAddMob) {
         double d = (double) packetAddMob.x / 32D;
         double d1 = (double) packetAddMob.y / 32D;
         double d2 = (double) packetAddMob.z / 32D;
         float f = (float) (packetAddMob.yaw * 360) / 256F;
         float f1 = (float) (packetAddMob.pitch * 360) / 256F;
-        Mob mob = (Mob) EntityDispatcher.getInstance().createEntity(packetAddMob.type, mc.currentWorld);
+        Mob mob = (Mob) EntityDispatcher.getInstance().createEntity(packetAddMob.type, this.mc.currentWorld);
         mob.serverPosX = packetAddMob.x;
         mob.serverPosY = packetAddMob.y;
         mob.serverPosZ = packetAddMob.z;
         mob.id = packetAddMob.id;
         mob.absMoveTo(d, d1, d2, f, f1);
         mob.isMultiplayerEntity = true;
-        worldClientMP.addEntityToWorld(packetAddMob.id, mob);
+        this.worldClientMP.addEntityToWorld(packetAddMob.id, mob);
         List<SynchedEntityData.DataItem<?>> list = packetAddMob.getUnpackedData();
-        if (list != null)
-        {
+        if (list != null) {
             mob.getEntityData().assignValues(list);
         }
         mob.nickname = StringUtils.substring(packetAddMob.nickname, 0, 32);
@@ -759,29 +677,25 @@ public class PacketHandlerClient extends PacketHandler
     }
 
     @Override
-    public void handleSetTime(@NotNull PacketSetTime packetSetTime)
-    {
-        mc.currentWorld.setWorldTime(packetSetTime.time);
+    public void handleSetTime(@NotNull PacketSetTime packetSetTime) {
+        this.mc.currentWorld.setWorldTime(packetSetTime.time);
     }
 
     @Override
-    public void handleSetSpawnPosition(@NotNull PacketSetSpawnPosition packetSetSpawnPosition)
-    {
-        mc.thePlayer.setPlayerSpawnPoint(new TilePos(packetSetSpawnPosition.x, packetSetSpawnPosition.y, packetSetSpawnPosition.z));
-        mc.currentWorld.getLevelData().setSpawn(packetSetSpawnPosition.x, packetSetSpawnPosition.y, packetSetSpawnPosition.z);
+    public void handleSetSpawnPosition(@NotNull PacketSetSpawnPosition packetSetSpawnPosition) {
+        this.mc.thePlayer.setPlayerSpawnPoint(new TilePos(packetSetSpawnPosition.x, packetSetSpawnPosition.y, packetSetSpawnPosition.z));
+        this.mc.currentWorld.getLevelData().setSpawn(packetSetSpawnPosition.x, packetSetSpawnPosition.y, packetSetSpawnPosition.z);
     }
 
     @Override
-    public void handleSetRiding(@NotNull PacketSetRiding packetSetRiding)
-    {
+    public void handleSetRiding(@NotNull PacketSetRiding packetSetRiding) {
         Entity passenger = getEntityByID(packetSetRiding.passengerId);
         IVehicle vehicle;
-        if (packetSetRiding.passengerId == mc.thePlayer.id)
-        {
-            passenger = mc.thePlayer;
+        if (packetSetRiding.passengerId == this.mc.thePlayer.id) {
+            passenger = this.mc.thePlayer;
         }
         if (packetSetRiding.isTileEntity) {
-            vehicle = (IVehicle) worldClientMP.getTileEntity(packetSetRiding.x, packetSetRiding.y, packetSetRiding.z);
+            vehicle = (IVehicle) this.worldClientMP.getTileEntity(packetSetRiding.x, packetSetRiding.y, packetSetRiding.z);
         } else {
             vehicle = getEntityByID(packetSetRiding.vehicleId);
         }
@@ -791,85 +705,64 @@ public class PacketHandlerClient extends PacketHandler
     }
 
     @Override
-    public void handleEntityEvent(@NotNull PacketEntityEvent packetEntityEvent)
-    {
+    public void handleEntityEvent(@NotNull PacketEntityEvent packetEntityEvent) {
         Entity entity = getEntityByID(packetEntityEvent.entityId);
-        if (entity != null)
-        {
+        if (entity != null) {
             entity.handleEntityEvent(packetEntityEvent.entityStatus, packetEntityEvent.attackedAtYaw);
         }
     }
 
-    protected Entity getEntityByID(int i)
-    {
-        if (i == mc.thePlayer.id)
-        {
-            return mc.thePlayer;
-        }
-        else
-        {
-            return worldClientMP.getEntityFromId(i);
+    protected Entity getEntityByID(int i) {
+        if (i == this.mc.thePlayer.id) {
+            return this.mc.thePlayer;
+        } else {
+            return this.worldClientMP.getEntityFromId(i);
         }
     }
 
     @Override
-    public void handleSetHealth(@NotNull PacketSetHealth packetSetHealth)
-    {
-        mc.thePlayer.setHealth(packetSetHealth.healthMP);
+    public void handleSetHealth(@NotNull PacketSetHealth packetSetHealth) {
+        this.mc.thePlayer.setHealth(packetSetHealth.healthMP);
     }
 
     @Override
-    public void handleUpdatePlayerProfile(@NotNull PacketUpdatePlayerProfile profilePacket)
-    {
+    public void handleUpdatePlayerProfile(@NotNull PacketUpdatePlayerProfile profilePacket) {
         PlayerProfile playerProfile = new PlayerProfile(profilePacket.username, profilePacket.nickname, profilePacket.uuid, profilePacket.score, profilePacket.chatColor, profilePacket.isOperator);
-        if (playerProfile.uuid.equals(mc.thePlayer.uuid))
-        {
-            mc.thePlayer.score = playerProfile.scoreTotal;
+        if (playerProfile.uuid.equals(this.mc.thePlayer.uuid)) {
+            this.mc.thePlayer.score = playerProfile.scoreTotal;
         }
         int index = findPlayerInList(playerProfile);
-        if (index != -1)
-        {
-            if (!profilePacket.isOnline)
-            {
+        if (index != -1) {
+            if (!profilePacket.isOnline) {
                 removePlayer(index);
+            } else {
+                this.players.set(index, playerProfile);
             }
-            else
-            {
-                players.set(index, playerProfile);
-            }
-        }
-        else
-        {
+        } else {
             addPlayer(playerProfile);
         }
     }
 
     @Override
-    public void handleRespawn(@NotNull PacketRespawn packetRespawn)
-    {
-        if (packetRespawn.respawnDimensionId != mc.thePlayer.dimension)
-        {
-            started = false;
-            worldClientMP = new WorldClientMP(this, worldClientMP.getLevelData().getRandomSeed(), packetRespawn.respawnDimensionId, packetRespawn.respawnWorldTypeId);
-            worldClientMP.isClientSide = true;
-            mc.changeWorld(worldClientMP);
-            mc.thePlayer.dimension = packetRespawn.respawnDimensionId;
-            mc.displayScreen(new ScreenDownloadTerrain(this));
+    public void handleRespawn(@NotNull PacketRespawn packetRespawn) {
+        if (packetRespawn.respawnDimensionId != this.mc.thePlayer.dimension) {
+            this.started = false;
+            this.worldClientMP = new WorldClientMP(this, this.worldClientMP.getLevelData().getRandomSeed(), packetRespawn.respawnDimensionId, packetRespawn.respawnWorldTypeId);
+            this.worldClientMP.isClientSide = true;
+            this.mc.changeWorld(this.worldClientMP);
+            this.mc.thePlayer.dimension = packetRespawn.respawnDimensionId;
+            this.mc.displayScreen(new ScreenDownloadTerrain(this));
         }
-        mc.respawn(true, packetRespawn.respawnDimensionId);
+        this.mc.respawn(true, packetRespawn.respawnDimensionId);
     }
 
     @Override
-    public void handleExplosion(@NotNull PacketExplosion packetExplosion)
-    {
+    public void handleExplosion(@NotNull PacketExplosion packetExplosion) {
         Explosion explosion;
-        if (packetExplosion.isCannonball)
-        {
-            explosion = new ExplosionCannonball(mc.currentWorld, null, packetExplosion.explosionX, packetExplosion.explosionY, packetExplosion.explosionZ, packetExplosion.explosionSize);
-        }
-        else
-        {
-            explosion = new Explosion(mc.currentWorld, null, packetExplosion.explosionX, packetExplosion.explosionY, packetExplosion.explosionZ, packetExplosion.explosionSize);
+        if (packetExplosion.isCannonball) {
+            explosion = new ExplosionCannonball(this.mc.currentWorld, null, packetExplosion.explosionX, packetExplosion.explosionY, packetExplosion.explosionZ, packetExplosion.explosionSize);
+        } else {
+            explosion = new Explosion(this.mc.currentWorld, null, packetExplosion.explosionX, packetExplosion.explosionY, packetExplosion.explosionZ, packetExplosion.explosionSize);
         }
         explosion.destroyedBlockPositions = packetExplosion.destroyedBlockPositions;
         //explosion.doExplosionA();
@@ -877,53 +770,52 @@ public class PacketHandlerClient extends PacketHandler
     }
 
     @Override
-    public void handleContainerOpen(@NotNull PacketContainerOpen packetContainerOpen)
-    {
+    public void handleContainerOpen(@NotNull PacketContainerOpen packetContainerOpen) {
         switch (packetContainerOpen.inventoryType) {
             case PacketContainerOpen.TYPE_GENERIC_CONTAINER: {
                 ContainerSimple simpleContainer = new ContainerSimple(packetContainerOpen.windowTitle, packetContainerOpen.slotsCount);
-                mc.thePlayer.displayContainerScreen(simpleContainer);
-                mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
+                this.mc.thePlayer.displayContainerScreen(simpleContainer);
+                this.mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
                 break;
             }
             case PacketContainerOpen.TYPE_FURNACE: {
                 TileEntityFurnace tileEntityFurnace = new TileEntityFurnace();
-                mc.thePlayer.displayFurnaceScreen(tileEntityFurnace);
-                mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
+                this.mc.thePlayer.displayFurnaceScreen(tileEntityFurnace);
+                this.mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
                 break;
             }
             case PacketContainerOpen.TYPE_DISPENSER: {
                 TileEntityDispenser tileEntityDispenser = new TileEntityDispenser();
-                mc.thePlayer.displayDispenserScreen(tileEntityDispenser);
-                mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
+                this.mc.thePlayer.displayDispenserScreen(tileEntityDispenser);
+                this.mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
                 break;
             }
             case PacketContainerOpen.TYPE_ACTIVATOR: {
                 TileEntityActivator tileEntityActivator = new TileEntityActivator();
-                mc.thePlayer.displayActivatorScreen(tileEntityActivator);
-                mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
+                this.mc.thePlayer.displayActivatorScreen(tileEntityActivator);
+                this.mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
                 break;
             }
             case PacketContainerOpen.TYPE_BLAST_FURNACE: {
                 TileEntityFurnaceBlast tileEntityFurnaceBlast = new TileEntityFurnaceBlast();
-                mc.thePlayer.displayBlastFurnaceScreen(tileEntityFurnaceBlast);
-                mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
+                this.mc.thePlayer.displayBlastFurnaceScreen(tileEntityFurnaceBlast);
+                this.mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
                 break;
             }
             case PacketContainerOpen.TYPE_TROMMEL: {
                 TileEntityTrommel tileEntityTrommel = new TileEntityTrommel();
-                mc.thePlayer.displayTrommelScreen(tileEntityTrommel);
-                mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
+                this.mc.thePlayer.displayTrommelScreen(tileEntityTrommel);
+                this.mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
                 break;
             }
             case PacketContainerOpen.TYPE_PAINTING: {
-                mc.thePlayer.displayPaintingPickerScreen();
+                this.mc.thePlayer.displayPaintingPickerScreen();
                 break;
             }
             case PacketContainerOpen.TYPE_CRAFTING: {
-                PlayerLocal playerLocal = mc.thePlayer;
-                mc.thePlayer.displayWorkbenchScreen(new TilePos(playerLocal.x, playerLocal.y, playerLocal.z));
-                mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
+                PlayerLocal playerLocal = this.mc.thePlayer;
+                this.mc.thePlayer.displayWorkbenchScreen(new TilePos(playerLocal.x, playerLocal.y, playerLocal.z));
+                this.mc.thePlayer.containerMenu.containerId = packetContainerOpen.windowId;
                 break;
             }
             default: {
@@ -933,65 +825,46 @@ public class PacketHandlerClient extends PacketHandler
     }
 
     @Override
-    public void handleFlagOpen(@NotNull PacketFlagOpen packetFlagOpen)
-    {
-        TileEntity tileEntity = worldClientMP.getTileEntity(packetFlagOpen.x, packetFlagOpen.y, packetFlagOpen.z);
-        if (tileEntity instanceof TileEntityFlag)
-        {
-            TileEntityFlag tileEntityFlag = (TileEntityFlag) tileEntity;
-            mc.thePlayer.displayFlagEditorScreen(tileEntityFlag);
-            mc.thePlayer.containerMenu.containerId = packetFlagOpen.windowId;
+    public void handleFlagOpen(@NotNull PacketFlagOpen packetFlagOpen) {
+        TileEntity tileEntity = this.worldClientMP.getTileEntity(packetFlagOpen.x, packetFlagOpen.y, packetFlagOpen.z);
+        if (tileEntity instanceof TileEntityFlag tileEntityFlag) {
+            this.mc.thePlayer.displayFlagEditorScreen(tileEntityFlag);
+            this.mc.thePlayer.containerMenu.containerId = packetFlagOpen.windowId;
         }
     }
 
     @Override
-    public void handlePhotoMode(@NotNull PacketPhotoMode packetPhotoMode)
-    {
+    public void handlePhotoMode(@NotNull PacketPhotoMode packetPhotoMode) {
         ScreenPause.photoModeDisabled = packetPhotoMode.disabled;
     }
 
     @Override
-    public void handleContainerSetSlot(@NotNull PacketContainerSetSlot packetContainerSetSlot)
-    {
-        if (packetContainerSetSlot.windowId == -1)
-        {
-            mc.thePlayer.inventory.setHeldItemStack(packetContainerSetSlot.myItemStack);
-        }
-        else if (packetContainerSetSlot.windowId == 0 && packetContainerSetSlot.itemSlot >= 36 && packetContainerSetSlot.itemSlot < 45)
-        {
-            ItemStack itemstack = mc.thePlayer.inventoryMenu.getSlot(packetContainerSetSlot.itemSlot).getItemStack();
-            if (packetContainerSetSlot.myItemStack != null && (itemstack == null || itemstack.stackSize < packetContainerSetSlot.myItemStack.stackSize))
-            {
+    public void handleContainerSetSlot(@NotNull PacketContainerSetSlot packetContainerSetSlot) {
+        if (packetContainerSetSlot.windowId == -1) {
+            this.mc.thePlayer.inventory.setHeldItemStack(packetContainerSetSlot.myItemStack);
+        } else if (packetContainerSetSlot.windowId == 0 && packetContainerSetSlot.itemSlot >= 36 && packetContainerSetSlot.itemSlot < 45) {
+            ItemStack itemstack = this.mc.thePlayer.inventoryMenu.getSlot(packetContainerSetSlot.itemSlot).getItemStack();
+            if (packetContainerSetSlot.myItemStack != null && (itemstack == null || itemstack.stackSize < packetContainerSetSlot.myItemStack.stackSize)) {
                 packetContainerSetSlot.myItemStack.animationsToGo = 5;
             }
-            mc.thePlayer.inventoryMenu.setItem(packetContainerSetSlot.itemSlot, packetContainerSetSlot.myItemStack);
-        }
-        else if (packetContainerSetSlot.windowId == mc.thePlayer.containerMenu.containerId)
-        {
-            mc.thePlayer.containerMenu.setItem(packetContainerSetSlot.itemSlot, packetContainerSetSlot.myItemStack);
+            this.mc.thePlayer.inventoryMenu.setItem(packetContainerSetSlot.itemSlot, packetContainerSetSlot.myItemStack);
+        } else if (packetContainerSetSlot.windowId == this.mc.thePlayer.containerMenu.containerId) {
+            this.mc.thePlayer.containerMenu.setItem(packetContainerSetSlot.itemSlot, packetContainerSetSlot.myItemStack);
         }
     }
 
     @Override
-    public void handleContainerAck(@NotNull PacketContainerAck packetContainerAck)
-    {
+    public void handleContainerAck(@NotNull PacketContainerAck packetContainerAck) {
         MenuAbstract container = null;
-        if (packetContainerAck.windowId == 0)
-        {
-            container = mc.thePlayer.inventoryMenu;
-        }
-        else if (packetContainerAck.windowId == mc.thePlayer.containerMenu.containerId)
-        {
-            container = mc.thePlayer.containerMenu;
-        }
-        if (container != null)
-        {
-            if (packetContainerAck.accepted)
-            {
+        if (packetContainerAck.windowId == 0) {
+            container = this.mc.thePlayer.inventoryMenu;
+        } else if (packetContainerAck.windowId == this.mc.thePlayer.containerMenu.containerId) {
+            container = this.mc.thePlayer.containerMenu;
+        }
+        if (container != null) {
+            if (packetContainerAck.accepted) {
                 container.deleteBackup(packetContainerAck.shortWindowId);
-            }
-            else
-            {
+            } else {
                 container.rollbackToBackup(packetContainerAck.shortWindowId);
                 addToSendQueue(new PacketContainerAck(packetContainerAck.windowId, packetContainerAck.shortWindowId, true));
             }
@@ -999,34 +872,26 @@ public class PacketHandlerClient extends PacketHandler
     }
 
     @Override
-    public void handleContainerSetContent(@NotNull PacketContainerSetContent packetContainerSetContent)
-    {
-        if (packetContainerSetContent.windowId == 0)
-        {
-            mc.thePlayer.inventoryMenu.setAll(packetContainerSetContent.stackList);
-        }
-        else if (packetContainerSetContent.windowId == mc.thePlayer.containerMenu.containerId)
-        {
-            mc.thePlayer.containerMenu.setAll(packetContainerSetContent.stackList);
+    public void handleContainerSetContent(@NotNull PacketContainerSetContent packetContainerSetContent) {
+        if (packetContainerSetContent.windowId == 0) {
+            this.mc.thePlayer.inventoryMenu.setAll(packetContainerSetContent.stackList);
+        } else if (packetContainerSetContent.windowId == this.mc.thePlayer.containerMenu.containerId) {
+            this.mc.thePlayer.containerMenu.setAll(packetContainerSetContent.stackList);
         }
     }
 
     @Override
-    public void handleContainerSetData(@NotNull PacketContainerSetData packetContainerSetData)
-    {
+    public void handleContainerSetData(@NotNull PacketContainerSetData packetContainerSetData) {
         handleInvalidPacket(packetContainerSetData);
-        if (mc.thePlayer.containerMenu != null && mc.thePlayer.containerMenu.containerId == packetContainerSetData.windowId)
-        {
-            mc.thePlayer.containerMenu.setData(packetContainerSetData.progressBar, packetContainerSetData.progressBarValue);
+        if (this.mc.thePlayer.containerMenu != null && this.mc.thePlayer.containerMenu.containerId == packetContainerSetData.windowId) {
+            this.mc.thePlayer.containerMenu.setData(packetContainerSetData.progressBar, packetContainerSetData.progressBarValue);
         }
     }
 
     @Override
-    public void handleSetEquippedItem(@NotNull PacketSetEquippedItem packetSetEquippedItem)
-    {
+    public void handleSetEquippedItem(@NotNull PacketSetEquippedItem packetSetEquippedItem) {
         Entity entity = getEntityByID(packetSetEquippedItem.entityID);
-        if (entity != null)
-        {
+        if (entity != null) {
             entity.setEquippedSlot(packetSetEquippedItem.slot, packetSetEquippedItem.itemID, packetSetEquippedItem.itemMeta, packetSetEquippedItem.itemData);
         }
     }
@@ -1040,87 +905,76 @@ public class PacketHandlerClient extends PacketHandler
     }
 
     @Override
-    public void handleContainerClose(@NotNull PacketContainerClose packetContainerClose)
-    {
-        mc.thePlayer.closeScreen();
+    public void handleContainerClose(@NotNull PacketContainerClose packetContainerClose) {
+        this.mc.thePlayer.closeScreen();
     }
 
     @Override
-    public void handleBlockEvent(@NotNull PacketBlockEvent packetBlockEvent)
-    {
-        mc.currentWorld.triggerEvent(packetBlockEvent.xLocation, packetBlockEvent.yLocation, packetBlockEvent.zLocation, packetBlockEvent.index, packetBlockEvent.data);
+    public void handleBlockEvent(@NotNull PacketBlockEvent packetBlockEvent) {
+        this.mc.currentWorld.triggerEvent(packetBlockEvent.xLocation, packetBlockEvent.yLocation, packetBlockEvent.zLocation, packetBlockEvent.index, packetBlockEvent.data);
     }
 
     @Override
-    public void handleBedMessage(@NotNull PacketBedMessage packetBedMessage)
-    {
+    public void handleBedMessage(@NotNull PacketBedMessage packetBedMessage) {
         int state = packetBedMessage.bedState;
-        if (state >= 0 && state < PacketBedMessage.BED_MESSAGE_KEYS.length && PacketBedMessage.BED_MESSAGE_KEYS[state] != null)
-        {
-            mc.thePlayer.sendTranslatedChatMessage(PacketBedMessage.BED_MESSAGE_KEYS[state]);
+        if (state >= 0 && state < PacketBedMessage.BED_MESSAGE_KEYS.length && PacketBedMessage.BED_MESSAGE_KEYS[state] != null) {
+            this.mc.thePlayer.sendTranslatedChatMessage(PacketBedMessage.BED_MESSAGE_KEYS[state]);
         }
     }
 
     @Override
-    public void handleMapData(@NotNull PacketMapData packetMapData)
-    {
-        if (packetMapData.itemId == Items.MAP.id)
-        {
-            ItemMap.getOrCreateSavedData(packetMapData.meta, packetMapData.scale, mc.currentWorld).setColors(packetMapData.mapData).setMapWaypoints(packetMapData.waypoints);
-        }
-        else
-        {
+    public void handleMapData(@NotNull PacketMapData packetMapData) {
+        if (packetMapData.itemId == Items.MAP.id) {
+            ItemMap.getOrCreateSavedData(packetMapData.meta, packetMapData.scale, this.mc.currentWorld).setColors(packetMapData.mapData).setMapWaypoints(packetMapData.waypoints);
+        } else {
             LOGGER.warn("Unexpected itemId: {}", packetMapData.itemId);
         }
     }
 
     @Override
-    public void handlePlaySoundEffect(@NotNull PacketPlaySound packetPlaySound)
-    {
-        mc.currentWorld.playBlockEvent(packetPlaySound.soundID, packetPlaySound.x, packetPlaySound.y, packetPlaySound.z, packetPlaySound.data);
+    public void handlePlaySoundEffect(@NotNull PacketPlaySound packetPlaySound) {
+        this.mc.currentWorld.playBlockEvent(packetPlaySound.soundID, packetPlaySound.x, packetPlaySound.y, packetPlaySound.z, packetPlaySound.data);
     }
 
-	@Override
-	public void handlePlaySoundDirectly(@NotNull PacketPlaySoundDirect packet) {
-		String soundPath = SoundTypes.getSoundById(packet.soundId);
-		if(soundPath == null) {
-			return;
-		}
-		mc.sndManager.playSoundAt(soundPath, packet.soundType, (float) packet.x, (float) packet.y, (float) packet.z, packet.volume, packet.pitch);
-	}
-    
     @Override
-    public void handleAddParticle(@NotNull PacketAddParticle packetAddParticle)
-    {
-        if (packetAddParticle.isGroup){
+    public void handlePlaySoundDirectly(@NotNull PacketPlaySoundDirect packet) {
+        String soundPath = SoundTypes.getSoundById(packet.soundId);
+        if (soundPath == null) {
+            return;
+        }
+        this.mc.sndManager.playSoundAt(soundPath, packet.soundType, (float) packet.x, (float) packet.y, (float) packet.z, packet.volume, packet.pitch);
+    }
+
+    @Override
+    public void handleAddParticle(@NotNull PacketAddParticle packetAddParticle) {
+        if (packetAddParticle.isGroup) {
             for (int i = 0; i < packetAddParticle.amount; i++) {
-                mc.renderGlobal.addParticle(packetAddParticle.particleKey,
-                        packetAddParticle.x + rand.nextDouble() * packetAddParticle.randOffX,
-                        packetAddParticle.y + rand.nextDouble() * packetAddParticle.randOffY,
-                        packetAddParticle.z + rand.nextDouble() * packetAddParticle.randOffZ,
-                        packetAddParticle.motionX + rand.nextGaussian() * packetAddParticle.randMotionX,
-                        packetAddParticle.motionY + rand.nextGaussian() * packetAddParticle.randMotionY,
-                        packetAddParticle.motionZ + rand.nextGaussian() * packetAddParticle.randMotionZ,
-                        packetAddParticle.data,
-                        packetAddParticle.maxDistance);
-            }
-        } else {
-            mc.renderGlobal.addParticle(packetAddParticle.particleKey,
-                    packetAddParticle.x,
-                    packetAddParticle.y,
-                    packetAddParticle.z,
-                    packetAddParticle.motionX,
-                    packetAddParticle.motionY,
-                    packetAddParticle.motionZ,
+                this.mc.renderGlobal.addParticle(packetAddParticle.particleKey,
+                    packetAddParticle.x + this.rand.nextDouble() * packetAddParticle.randOffX,
+                    packetAddParticle.y + this.rand.nextDouble() * packetAddParticle.randOffY,
+                    packetAddParticle.z + this.rand.nextDouble() * packetAddParticle.randOffZ,
+                    packetAddParticle.motionX + this.rand.nextGaussian() * packetAddParticle.randMotionX,
+                    packetAddParticle.motionY + this.rand.nextGaussian() * packetAddParticle.randMotionY,
+                    packetAddParticle.motionZ + this.rand.nextGaussian() * packetAddParticle.randMotionZ,
                     packetAddParticle.data,
                     packetAddParticle.maxDistance);
+            }
+        } else {
+            this.mc.renderGlobal.addParticle(packetAddParticle.particleKey,
+                packetAddParticle.x,
+                packetAddParticle.y,
+                packetAddParticle.z,
+                packetAddParticle.motionX,
+                packetAddParticle.motionY,
+                packetAddParticle.motionZ,
+                packetAddParticle.data,
+                packetAddParticle.maxDistance);
         }
 
     }
 
     @Override
-    public void handleStatistic(final @NotNull PacketStatistic packetStatistic)
-    {
+    public void handleStatistic(final @NotNull PacketStatistic packetStatistic) {
         NamespaceID id;
         try {
             id = NamespaceID.fromPool(packetStatistic.statID);
@@ -1134,14 +988,13 @@ public class PacketHandlerClient extends PacketHandler
             return;
         }
         if (stat.clientside) return; // Don't allow server to give client side only stats
-        mc.thePlayer.addStat(stat, packetStatistic.valueChange);
+        this.mc.thePlayer.addStat(stat, packetStatistic.valueChange);
     }
 
     @Override
-    public void handlePlayerGamemode(@NotNull PacketPlayerGamemode packet)
-    {
+    public void handlePlayerGamemode(@NotNull PacketPlayerGamemode packet) {
         Entity entity = getEntityByID(packet.entityId);
-        if (entity instanceof Player){
+        if (entity instanceof Player) {
             final @Nullable Gamemode gamemodeFromPacket = Registries.GAMEMODES.getItem(packet.gamemodeId);
             if (gamemodeFromPacket != null) {
                 ((Player) entity).setGamemode(gamemodeFromPacket);
@@ -1150,8 +1003,7 @@ public class PacketHandlerClient extends PacketHandler
     }
 
     @Override
-    public void handleEntityNickname(@NotNull PacketEntityNickname packetEntityNickname)
-    {
+    public void handleEntityNickname(@NotNull PacketEntityNickname packetEntityNickname) {
         Entity entity = getEntityByID(packetEntityNickname.entityId);
 
         if (entity instanceof Mob) {
@@ -1161,40 +1013,34 @@ public class PacketHandlerClient extends PacketHandler
     }
 
     @Override
-    public boolean isServerHandler()
-    {
+    public boolean isServerHandler() {
         return false;
     }
-    
+
     @Override
     public void handleSetCarriedItem(@NotNull PacketSetCarriedItem packetSetCarriedItem) {
-        mc.thePlayer.inventory.setCurrentSlot(packetSetCarriedItem.id, true);
+        this.mc.thePlayer.inventory.setCurrentSlot(packetSetCarriedItem.id, true);
     }
 
     @Override
-    public void handleTileEntityData(@NotNull PacketTileEntityData packetTileEntityData)
-    {
+    public void handleTileEntityData(@NotNull PacketTileEntityData packetTileEntityData) {
         Class<?> clazz = TileEntityDispatcher.getClassFromID(packetTileEntityData.tag.getString("id"));
         if (clazz == null) return;
-        TileEntity existingTileEntity = worldClientMP.getTileEntity(packetTileEntityData.tag.getInteger("x"), packetTileEntityData.tag.getInteger("y"), packetTileEntityData.tag.getInteger("z"));
-        if (existingTileEntity == null || existingTileEntity.getClass() != clazz)
-        {
+        TileEntity existingTileEntity = this.worldClientMP.getTileEntity(packetTileEntityData.tag.getInteger("x"), packetTileEntityData.tag.getInteger("y"), packetTileEntityData.tag.getInteger("z"));
+        if (existingTileEntity == null || existingTileEntity.getClass() != clazz) {
             TileEntity tileEntity = TileEntityDispatcher.createAndLoadEntity(packetTileEntityData.tag);
-            if (tileEntity != null)
-            {
-                mc.currentWorld.setTileEntity(tileEntity.x, tileEntity.y, tileEntity.z, tileEntity);
+            if (tileEntity != null) {
+                this.mc.currentWorld.setTileEntity(tileEntity.x, tileEntity.y, tileEntity.z, tileEntity);
             }
-        }
-        else
-        {
+        } else {
             existingTileEntity.readFromNBT(packetTileEntityData.tag);
         }
-        worldClientMP.markBlockDirty(packetTileEntityData.tag.getInteger("x"), packetTileEntityData.tag.getInteger("y"), packetTileEntityData.tag.getInteger("z"));
+        this.worldClientMP.markBlockDirty(packetTileEntityData.tag.getInteger("x"), packetTileEntityData.tag.getInteger("y"), packetTileEntityData.tag.getInteger("z"));
     }
 
     @Override
     public void handleGameRule(@NotNull PacketGameRule packet) {
-        LevelData levelData = mc.currentWorld.getLevelData();
+        LevelData levelData = this.mc.currentWorld.getLevelData();
         if (packet.getGameRules() != null) {
             levelData.getGameRules().setValues(packet.getGameRules());
         }
@@ -1202,11 +1048,11 @@ public class PacketHandlerClient extends PacketHandler
 
     @Override
     public void handleRecipeSync(@NotNull PacketRecipeSync packetRecipeSync) {
-        if(Registries.RECIPES.getAllSerializableRecipes().isEmpty()){
+        if (Registries.RECIPES.getAllSerializableRecipes().isEmpty()) {
             LOGGER.info("Receiving {} recipes from server..", packetRecipeSync.maxRecipes);
         }
         DataLoader.loadRecipeFromServer(packetRecipeSync);
-        if(Registries.RECIPES.getAllSerializableRecipes().size() == packetRecipeSync.maxRecipes){
+        if (Registries.RECIPES.getAllSerializableRecipes().size() == packetRecipeSync.maxRecipes) {
             LOGGER.info("All recipes received!");
             Registries.RECIPES.invalidateCaches();
             GuidebookPageSearch.searchField.setText("_");
@@ -1217,7 +1063,7 @@ public class PacketHandlerClient extends PacketHandler
             ScreenGuidebook.getPageManager().updatePages();
         }
     }
-    
+
     @Override
     public void handleSyncIDs(@NotNull PacketSyncIDs packetSyncIDs) {
         if (packetSyncIDs.destinationId == PacketSyncIDs.DESTINATION_SOUND_IDS) {
@@ -1226,14 +1072,14 @@ public class PacketHandlerClient extends PacketHandler
             EntityDispatcher.getInstance().setNumericIds(packetSyncIDs.mapping);
         }
     }
-    
+
     @Override
     public void handleCustomPayload(@NotNull PacketCustomPayload packetCustomPayload) {
-        if(PacketCustomPayload.CHANNEL_RAINBOW_START.equals(packetCustomPayload.channel)) {
+        if (PacketCustomPayload.CHANNEL_RAINBOW_START.equals(packetCustomPayload.channel)) {
 //            System.out.printf("b0:%s b1:%s b2:%s b3:%s\n", packet.data[0], packet.data[1], packet.data[2], packet.data[3]);
             int rainbowTicks = Byte.toUnsignedInt(packetCustomPayload.data[0]) << 24 | Byte.toUnsignedInt(packetCustomPayload.data[1]) << 16 | Byte.toUnsignedInt(packetCustomPayload.data[2]) << 8 | Byte.toUnsignedInt(packetCustomPayload.data[3]);
 //            System.out.println("Added rainbow with " + rainbowTicks + " ticks");
-            worldClientMP.addRainbow(rainbowTicks);
+            this.worldClientMP.addRainbow(rainbowTicks);
         }
     }
 
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 19b3025f6..dd0cf79de 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
@@ -6,7 +6,6 @@ import static com.b100.utils.StreamUtils.*;
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.File;
-import java.net.URL;
 import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.List;
@@ -19,6 +18,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.option.GameSettings;
 import net.minecraft.client.sound.SoundEngine;
 import net.minecraft.client.sound.SoundRepository;
 import net.minecraft.core.net.CertificateHelper;
@@ -53,7 +53,7 @@ public class ThreadDownloadResources extends Thread {
         try {
             // Copy files out of jar
             for (String extractResource : extractFiles) {
-                File output = new File(resourcesFolder, "minecraft/sounds/" + extractResource);
+                File output = new File(this.resourcesFolder, "minecraft/sounds/" + extractResource);
                 if (!output.exists()) {
                     transferDataAndClose(ThreadDownloadResources.class.getResourceAsStream("/assets/minecraft/sounds/" + extractResource), Files.newOutputStream(createNewFile(output).toPath()));
                 }
@@ -64,13 +64,13 @@ public class ThreadDownloadResources extends Thread {
         }
 
         try {
-            if (mc.gameSettings.downloadSoundfiles.value) {
+            if (GameSettings.DOWNLOAD_SOUNDFILES.value) {
                 LOGGER.info("Downloading sounds...");
                 try {
                     downloadResources();
                 } catch (Exception e) {
-                    downloading = ThreadDownloadState.ERROR;
-                    timeOfError = System.currentTimeMillis();
+                    this.downloading = ThreadDownloadState.ERROR;
+                    this.timeOfError = System.currentTimeMillis();
                     LOGGER.error("Error downloading sounds...", e);
                 }
             }
@@ -103,10 +103,10 @@ public class ThreadDownloadResources extends Thread {
                 String fileName = remapDirectory(name);
                 long size = tag.getAsContentTag().get("Size").getAsStringTag().getLong();
 
-                File soundFile = new File(resourcesFolder, "minecraft/sounds/" + fileName);
+                File soundFile = new File(this.resourcesFolder, "minecraft/sounds/" + fileName);
                 soundFile.mkdirs();
 
-                if (!soundFile.isFile() || (!mc.gameSettings.allowSoundOverrides.value && soundFile.length() != size)) {
+                if (!soundFile.isFile() || (!GameSettings.ALLOW_SOUND_OVERRIDES.value && soundFile.length() != size)) {
                     entries.add(new SoundEntry(soundFile, name, size));
                 }
             }
@@ -116,13 +116,13 @@ public class ThreadDownloadResources extends Thread {
             return;
         }
 
-        downloading = ThreadDownloadState.DOWNLOADING;
-        toDownload = entries.size();
+        this.downloading = ThreadDownloadState.DOWNLOADING;
+        this.toDownload = entries.size();
 
         for (SoundEntry soundEntry : entries) {
             try {
                 downloadSoundFile(soundEntry.name, soundEntry.file);
-                downloadProgress.incrementAndGet();
+                this.downloadProgress.incrementAndGet();
             } catch (Exception e) {
                 throw new RuntimeException("Error downloading sound file: " + soundEntry.name, e);
             }
@@ -130,9 +130,9 @@ public class ThreadDownloadResources extends Thread {
         SoundRepository.reload();
         this.mc.sndManager.destroy();
         this.mc.sndManager = new SoundEngine();
-        this.mc.sndManager.init(this.mc.gameSettings);
+        this.mc.sndManager.init();
 
-        downloading = ThreadDownloadState.IDLE;
+        this.downloading = ThreadDownloadState.IDLE;
     }
 
     private String remapDirectory(String path) {
@@ -161,21 +161,11 @@ public class ThreadDownloadResources extends Thread {
         transferDataAndClose(new BufferedInputStream(CertificateHelper.getWebsiteAsStream(url)), new BufferedOutputStream(Files.newOutputStream(createNewFile(file).toPath())));
     }
 
-    private static class SoundEntry {
-        private final File file;
-        private final String name;
-        private final long size;
+    private record SoundEntry(File file, String name, long size) { }
 
-        public SoundEntry(File file, String name, long size) {
-            this.file = file;
-            this.name = name;
-            this.size = size;
-        }
-    }
-
-    public static enum ThreadDownloadState {
+    public enum ThreadDownloadState {
         IDLE,
         DOWNLOADING,
-        ERROR;
+        ERROR
     }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/option/GameSettings.java b/game/client/src/main/java/net/minecraft/client/option/GameSettings.java
index b0262b031..652a073fa 100644
--- a/game/client/src/main/java/net/minecraft/client/option/GameSettings.java
+++ b/game/client/src/main/java/net/minecraft/client/option/GameSettings.java
@@ -1,630 +1,712 @@
 package net.minecraft.client.option;
 
-import static net.minecraft.core.util.Util.emptyStringIfNull;
-import static org.lwjgl.input.Keyboard.*;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
 import com.mojang.logging.LogUtils;
-
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.objects.ObjectArrayList;
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.ScaledResolution;
 import net.minecraft.client.discord.RichPresenceHandlerThread;
 import net.minecraft.client.enums.MusicFrequency;
 import net.minecraft.client.gui.TooltipElement;
 import net.minecraft.client.gui.hud.component.HudComponents;
 import net.minecraft.client.gui.options.ScreenOptions;
 import net.minecraft.client.input.InputDevice;
+import net.minecraft.client.option.enums.CloudQuality;
 import net.minecraft.client.option.enums.Colorblindness;
-import net.minecraft.client.render.font.Fonts;
 import net.minecraft.client.option.enums.DescriptionPromptEnum;
+import net.minecraft.client.option.enums.LeavesQuality;
+import net.minecraft.client.option.enums.LightmapStyle;
+import net.minecraft.client.option.enums.MipmapType;
+import net.minecraft.client.option.enums.ParticlesQuality;
+import net.minecraft.client.option.enums.RenderScale;
+import net.minecraft.client.option.enums.TextOutlineQuality;
+import net.minecraft.client.option.enums.TextureAnimation;
+import net.minecraft.client.render.font.Fonts;
 import net.minecraft.client.world.chunk.provider.SelectedProvider;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.enums.ChatVisibility;
 import net.minecraft.core.enums.Difficulty;
-import net.minecraft.client.option.enums.LightmapStyle;
-import net.minecraft.client.option.enums.MipmapType;
-import net.minecraft.client.option.enums.RenderScale;
 import net.minecraft.core.enums.PlacementMode;
-import net.minecraft.core.lang.I18n;
 import net.minecraft.core.sound.SoundCategory;
 import net.minecraft.core.util.helper.Color;
-import net.minecraft.core.util.helper.ITranslatable;
-
 import net.minecraft.core.util.helper.MathHelper;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.lwjgl.input.Keyboard;
 import org.slf4j.Logger;
 
-public class GameSettings {
-	private static final Logger LOGGER = LogUtils.getLogger();
-	private static final String[] ANIMATIONS = { "options.animations.off", "options.animations.procedural", "options.animations.custom" };
-
-	public final Minecraft mc;
-	private final File optionsFile;
-
-	public @NotNull OptionInteger windowWidth = new OptionInteger(this, "windowWidth", 854);
-	public @NotNull OptionInteger windowHeight = new OptionInteger(this, "windowHeight", 480);
-	
-	public @NotNull OptionVolume masterVolume = new OptionVolume(this, "sound.master", 1.0f, SoundCategory.GUI_SOUNDS);
-	public @NotNull OptionVolume musicVolume = new OptionVolume(this, "sound.music", 1.0f, SoundCategory.MUSIC);
-	public @NotNull OptionVolume worldSoundsVolume = new OptionVolume(this, "sound.world", 1.0f, SoundCategory.WORLD_SOUNDS);
-	public @NotNull OptionVolume entitySoundsVolume = new OptionVolume(this, "sound.entity", 1.0f, SoundCategory.ENTITY_SOUNDS);
-	public @NotNull OptionVolume caveSoundsVolume = new OptionVolume(this, "sound.cave", 1.0f, SoundCategory.CAVE_SOUNDS);
-	public @NotNull OptionVolume guiSoundsVolume = new OptionVolume(this, "sound.gui", 1.0f, SoundCategory.GUI_SOUNDS);
-	public @NotNull OptionVolume weatherSoundsVolume = new OptionVolume(this, "sound.weather", 1.0f, SoundCategory.WEATHER_SOUNDS);
-	public @NotNull OptionBoolean playTitleScreenMusic = new OptionBoolean(this, "playTitleScreenMusic", false);
-	
-	public @NotNull OptionFloat FoV = new OptionFloat(this, "fov", 0.40140846f);
-	public @NotNull OptionFloat mouseSensitivity = new OptionFloat(this, "mouseSensitivity", 0.5f);
-	public @NotNull OptionFloat screenPadding = new OptionFloat(this, "screenPadding", 0.0f);
-	public @NotNull OptionFloat gamma = new OptionFloat(this, "gamma", 0.5f);
-	public @NotNull OptionFloat brightness = new OptionFloat(this, "brightness", 0.5f);
-
-	public @NotNull OptionFloat fxaa = new OptionFloat(this, "fxaa", 0.0f);
-	public @NotNull OptionFloat controllerSensitivity = new OptionFloat(this, "controllerSensitivity", 0.5f);
-	public @NotNull OptionFloat controllerMenuSensitivity = new OptionFloat(this, "controllerMenuSensitivity", 0.5f);
-	public @NotNull OptionFloat controllerDeadzoneLeft = new OptionFloat(this, "controllerDeadzoneL", 0.25f);
-	public @NotNull OptionFloat controllerDeadzoneRight = new OptionFloat(this, "controllerDeadzoneR", 0.25f);
-	public @NotNull OptionFloat blockOutlineWidth = new OptionFloat(this, "blockOutlineWidth", 0.25f);
-	
-	public @NotNull OptionFloat flightSpeed = new OptionFloat(this, "flightSpeed", 0.5f);
-	public @NotNull OptionFloat flightSmoothness = new OptionFloat(this, "flightSmoothness", 0.5f);
-
-	public @NotNull OptionBoolean invertMouse = new OptionBoolean(this, "invertYMouse", false);
-	public @NotNull OptionBoolean rawMouseInput = new OptionBoolean(this, "rawMouseInput", false);
-	public @NotNull OptionBoolean viewBobbing = new OptionBoolean(this, "bobView", true);
-//	public @NotNull OptionBoolean advancedOpenGL = new OptionBoolean(this, "advancedOpengl", false);
-	public @NotNull OptionRange fancyGraphics = new OptionRange(this, "fancyGraphics", 1, 2);
-	public @NotNull OptionBoolean treeShadows = new OptionBoolean(this, "treeShadows", true);
-	public @NotNull OptionBoolean connectedGlass = new OptionBoolean(this, "connectedGlass", false);
-	public @NotNull OptionBoolean ambientOcclusion = new OptionBoolean(this, "ambientOcclusion", true);
-	public @NotNull OptionBoolean items3D = new OptionBoolean(this, "3Ditems", false);
-	public @NotNull OptionBoolean smoothCamera = new OptionBoolean(this, "smoothCamera", false);
-	public @NotNull OptionBoolean lockCamera = new OptionBoolean(this, "lockCamera", false);
-	public @NotNull OptionBoolean biomeWater = new OptionBoolean(this, "biomeWater", true);
-	public @NotNull OptionBoolean vignette = new OptionBoolean(this, "vignette", true);
-	public @NotNull OptionBoolean showPlayerList = new OptionBoolean(this, "showPlayerList", false);
-	public @NotNull OptionBoolean slimeParticles = new OptionBoolean(this, "slimeParticles", true);
-//	public @NotNull OptionBoolean disableShaders = new OptionBoolean(this, "disableShaders", false);
-	public @NotNull OptionString shaderOverride = new OptionString(this, "shaderOverride", "");
-	public @NotNull OptionBoolean autoHit = new OptionBoolean(this, "autoHit", true);
-	public @NotNull OptionBoolean easyBridge = new OptionBoolean(this, "easyBridge", true);
-	public @NotNull OptionBoolean foodHealthRegenOverlay = new OptionBoolean(this, "foodHealthRegenOverlay", true);
-	public @NotNull OptionBoolean fpsInOverlay = new OptionBoolean(this, "fpsInOverlay", false);
-	public @NotNull OptionBoolean versionInOverlay = new OptionBoolean(this, "versionInOverlay", false);
-	public @NotNull OptionBoolean controllerSwapShoulderButtons = new OptionBoolean(this, "controllerSwapShoulderButtons", false);
-	public @NotNull OptionBoolean controllerSwapAB = new OptionBoolean(this, "controllerSwapAB", false);
-	public @NotNull OptionBoolean controllerSwapXY = new OptionBoolean(this, "controllerSwapXY", false);
-	public @NotNull OptionBoolean clouds = new OptionBoolean(this, "clouds", true);
-	public @NotNull OptionFloat cloudHeight = new OptionFloat(this, "cloudHeight", 0f);
-	public @NotNull OptionFloat entityRenderDistance = new OptionFloat(this, "entityRenderDistance", 1f);
-	public @NotNull OptionBoolean armorDurabilityOverlay = new OptionBoolean(this, "armorDurabilityOverlay", false);
-	public @NotNull OptionBoolean armorProtectionOverlay = new OptionBoolean(this, "armorProtectionOverlay", true);
-	public @NotNull OptionBoolean heldItemCountOverlay = new OptionBoolean(this, "heldItemCountOverlay", false);
-	public @NotNull OptionBoolean pauseOnLostFocus = new OptionBoolean(this, "pauseOnLostFocus", true);
-	public @NotNull OptionBoolean showDebugScreen = new OptionBoolean(this, "showDebugScreen", false);
-	public @NotNull OptionBoolean showFrameTimes = new OptionBoolean(this, "showFrameTimes", false);
-	public @NotNull OptionBoolean showItemDebugInfo = new OptionBoolean(this, "showItemDebugInfo", false);
-	public @NotNull OptionBoolean showChunkBorders = new OptionBoolean(this, "showChunkBorders", false);
-	public @NotNull OptionBoolean showCollisionBoxes = new OptionBoolean(this, "showCollisionBoxes", false);
-	public @NotNull OptionBoolean swapCraftingButtons = new OptionBoolean(this, "swapCraftingButtons", false);
-	public @NotNull OptionBoolean forceOnscreenKeyboard = new OptionBoolean(this, "forceOnscreenKeyboard", false);
-	public @NotNull OptionEnum<PlacementMode> placementMode = new OptionEnum<>(this, "placementMode", PlacementMode.class, PlacementMode.DEFAULT).setIsSlider(false);
-	public @NotNull OptionBoolean discordRichPresence = new OptionBoolean(this, "discordRichPresence", false);
-	public @NotNull OptionImmersiveMode immersiveMode = new OptionImmersiveMode(this);
-	public @NotNull OptionColor guiBackgroundColor = new OptionColor(this, "guiBackgroundColor", new Color().setARGB(0xc0101010));
-	public @NotNull OptionEnum<Difficulty> difficulty = new OptionEnum<>(this, "difficulty", Difficulty.class, Difficulty.NORMAL); // Stub for local difficulty setting
-	public @NotNull OptionInteger thirdPersonView = new OptionInteger(this, "thirdPersonView", 0);
-	public @NotNull OptionRange renderDistance = new OptionRange(this, "renderDistance", 12, 2, 32);
-	public @NotNull OptionBoolean enableVsync = new OptionBoolean(this, "enableVsync", false);
-	public @NotNull OptionEnum<ChatVisibility> chatVisibility = new OptionEnum<>(this, "chatVisibility", ChatVisibility.class, ChatVisibility.SHOW_ALL);
-	public @NotNull OptionRange customFpsLimit = new OptionRange(this,"customFpsLimit",165,301);
-	public @NotNull OptionInteger guiScale = new OptionInteger(this, "guiScale", 0);
-	public @NotNull OptionInteger overlayMode = new OptionInteger(this, "overlayMode", 0);
-	public @NotNull OptionInteger rotationOverlayMode = new OptionInteger(this, "rotationOverlayMode", 0);
-	public @NotNull OptionRange animations = new OptionRange(this, "animations", 2, 3);
-	public @NotNull OptionBoolean customAnimations = new OptionBoolean(this, "customAnimations", true);
-	public @NotNull OptionInteger playerListPosition = new OptionInteger(this, "playerListPosition", 2);
-	public @NotNull OptionBoolean heldItemTooltips = new OptionBoolean(this, "heldItemTooltips", true);
-	public @NotNull OptionFloat colorCorrection = new OptionFloat(this, "colorCorrection", 0.5f);
-	public @NotNull OptionBoolean sneakToggle = new OptionBoolean(this, "sneakToggle", false);
-	public @NotNull OptionFloat autosaveTimer = new OptionFloat(this, "autosaveTimer", 0.04166666666F);
-	public @NotNull OptionBoolean enableItemDragging = new OptionBoolean(this, "enableItemDragging", true);
-	public @NotNull OptionRange bloom = new OptionRange(this, "bloom", 0, 3);
-	public @NotNull OptionEnum<RenderScale> renderScale = new OptionEnum<>(this, "renderScale", RenderScale.class, RenderScale.SCALE_100);
-	public @NotNull OptionBoolean heatHaze = new OptionBoolean(this, "heatHaze", false);
-	public @NotNull OptionBoolean alphaMenu = new OptionBoolean(this, "old", false);
-	public @NotNull OptionBoolean enableItemClumping = new OptionBoolean(this, "enableItemClumping", true);
-	public @NotNull OptionEnum<DescriptionPromptEnum> itemDescriptions = new OptionEnum<>(this, "itemDescriptions", DescriptionPromptEnum.class, DescriptionPromptEnum.PROMPT);
-	public @NotNull OptionBoolean turnWithVehicle = new OptionBoolean(this, "turnWithVehicle", true);
-	public @NotNull OptionBoolean disableCrashHandler = new OptionBoolean(this, "disableCrashHandler", false);
-//	public @NotNull OptionBoolean enableMultiDrawRendering = new OptionBoolean(this, "enableMultiDrawRendering", true);
-	public @NotNull OptionEnum<SelectedProvider> enableThreadedChunkProvider = new OptionEnum<>(this, "enableThreadedChunkProvider", SelectedProvider.class, SelectedProvider.THREADED);
-	public @NotNull OptionBoolean musicToasts = new OptionBoolean(this, "musicToasts", true);
-	public @NotNull OptionEnum<MusicFrequency> musicFrequency = new OptionEnum<>(this, "musicFrequency", MusicFrequency.class, MusicFrequency.DEFAULT);
-
-	public @NotNull OptionBoolean enableDevResourceLoading = new OptionBoolean(this, "enableDevResourceLoading", false);
-	public @NotNull OptionBoolean downloadSoundfiles = new OptionBoolean(this, "downloadSoundfiles", true);
-	public @NotNull OptionBoolean allowSoundOverrides = new OptionBoolean(this, "allowSoundOverrides", false);
-	public @NotNull OptionBoolean loadAllSounds = new OptionBoolean(this, "loadAllSounds", false);
-	
-	public @NotNull OptionBoolean overlayShowCoords = new OptionBoolean(this, "overlayShowCoords", true);
-	public @NotNull OptionBoolean overlayShowDirection = new OptionBoolean(this, "overlayShowDirection", true);
-	public @NotNull OptionBoolean overlayShowTime = new OptionBoolean(this, "overlayShowTime", true);
-	public @NotNull OptionBoolean overlayShowSeason = new OptionBoolean(this, "overlayShowSeason", true);
-	public @NotNull OptionBoolean overlayShowWeather = new OptionBoolean(this, "overlayShowWeather", true);
-	public @NotNull OptionBoolean overlayShowBiome = new OptionBoolean(this, "overlayShowBiome", true);
-	
-	public @NotNull OptionBoolean @NotNull [] overlayElements = new OptionBoolean[] { overlayShowCoords, overlayShowDirection, overlayShowTime, overlayShowSeason, overlayShowWeather, overlayShowBiome };
-	
-	public @NotNull OptionString lastServer = new OptionString(this, "lastServer", "");
-	public @NotNull OptionString skin = new OptionString(this, "skin", "Default");
-	public @NotNull OptionString selectedController = new OptionString(this, "selectedController", "");
-    public @NotNull OptionString language = new OptionString(this, "language", "en_US");
-	
-	public @NotNull OptionRange mipmapLevels = new OptionRange(this, "mipmapLevels", 0, 5);
-	public @NotNull OptionEnum<MipmapType> mipmapType = new OptionEnum<>(this, "mipmapType", MipmapType.class, MipmapType.SMOOTH);
-
-	public @NotNull OptionBoolean fovModification = new OptionBoolean(this, "fov.modification", true);
-	public @NotNull OptionBoolean screenMotionEffects = new OptionBoolean(this, "screen.motion.effects", true);
-
-	public @NotNull OptionBoolean fullscreen = new OptionBoolean(this, "fullscreen", Minecraft.isClientASteamDeck());
-	public @NotNull OptionBoolean borderlessFullscreen = new OptionBoolean(this, "borderlessFullscreen", true);
-	public @NotNull OptionBoolean startInFullscreen = new OptionBoolean(this, "startInFullscreen", true);
-	public @NotNull OptionTooltip tooltipStyle = new OptionTooltip(this, "tooltipStyle", "default");
-	public @NotNull OptionFont font = new OptionFont(this, "font", Fonts.DEFAULT);
-	public @NotNull OptionEnum<LightmapStyle> lightmapStyle = new OptionEnum<>(this, "lightmapStyle", LightmapStyle.class, LightmapStyle.GRAY);
-	public @NotNull OptionBoolean customLightmap = new OptionBoolean(this, "customLightmap", true);
-	public @NotNull OptionBoolean fog = new OptionBoolean(this, "fog", true);
-	public @NotNull OptionBoolean hideUndiscoveredItems = new OptionBoolean(this, "hideUndiscoveredItems", true);
-	public @NotNull OptionBoolean muteOnLostFocus = new OptionBoolean(this, "muteOnLostFocus", false);
-	public @NotNull OptionBoolean aurora = new OptionBoolean(this, "aurora", true);
-	public @NotNull OptionBoolean mobVariants = new OptionBoolean(this, "mobVariants", true);
-	public @NotNull OptionEnum<Colorblindness> colorblindnessFix = new OptionEnum<>(this, "colorblindnessFix", Colorblindness.class, Colorblindness.NONE);
-	public @NotNull OptionBoolean subtitles = new OptionBoolean(this, "subtitles", false);
-	public @NotNull OptionBoolean developerMode = new OptionBoolean(this, "developerMode", false);
-	public @NotNull OptionBoolean viewSupportMode = new OptionBoolean(this, "viewSupportMode", false);
-	public @NotNull OptionBoolean enableHolidayTextures = new OptionBoolean(this, "enableHolidayTextures", true);
-	public @NotNull OptionBoolean dynamicCursor = new OptionBoolean(this, "dynamicCursor", true);
-	public @NotNull OptionBoolean devModels = new OptionBoolean(this, "devModels", true);
-	public @NotNull OptionBoolean doJCECheck = new OptionBoolean(this, "doJCECheck", true);
-	public @NotNull OptionString uuidServer = new OptionString(this, "uuidServer", "https://api.minecraftservices.com/minecraft/profile/lookup/name/%s");
-
-	public @NotNull OptionBoolean playerLeftHanded = new OptionBoolean(this, "player.left.handed", false);
-	public @NotNull OptionBoolean playerCape = new OptionBoolean(this, "player.cape", true);
-	public @NotNull OptionBoolean playerHat = new OptionBoolean(this, "player.hat", true);
-	public @NotNull OptionBoolean playerJacket = new OptionBoolean(this, "player.jacket", true);
-	public @NotNull OptionBoolean playerSleeveLeft = new OptionBoolean(this, "player.sleeve.left", true);
-	public @NotNull OptionBoolean playerSleeveRight = new OptionBoolean(this, "player.sleeve.right", true);
-	public @NotNull OptionBoolean playerPantLeft = new OptionBoolean(this, "player.pant.left", true);
-	public @NotNull OptionBoolean playerPantRight = new OptionBoolean(this, "player.pant.right", true);
-	public @NotNull OptionBoolean playerDevModel = new OptionBoolean(this, "player.devmodel", true);
-	public @NotNull OptionEnum<Player.PlayerConfig.HurtSound> playerHurtSound = new OptionEnum<>(this, "player.hurtsound", Player.PlayerConfig.HurtSound.class, Player.PlayerConfig.HurtSound.MASCULINE);
-
-	public @NotNull KeyBinding keyAttack = new KeyBinding("key.attack").setDefault(InputDevice.mouse, 0);
-	public @NotNull KeyBinding keyInteract = new KeyBinding("key.interact").setDefault(InputDevice.mouse, 1);
-	public @NotNull KeyBinding keyPickBlock = new KeyBinding("key.pickBlock").setDefault(InputDevice.mouse, 2);
-	public @NotNull KeyBinding keySortInventory = new KeyBinding("key.sortInventory").setDefault(InputDevice.mouse, 2);
-	public @NotNull KeyBinding keyForward = new KeyBinding("key.forward").setDefault(InputDevice.keyboard, KEY_W);
-	public @NotNull KeyBinding keyLeft = new KeyBinding("key.left").setDefault(InputDevice.keyboard, KEY_A);
-	public @NotNull KeyBinding keyBack = new KeyBinding("key.back").setDefault(InputDevice.keyboard, KEY_S);
-	public @NotNull KeyBinding keyRight = new KeyBinding("key.right").setDefault(InputDevice.keyboard, KEY_D);
-	public @NotNull KeyBinding keyJump = new KeyBinding("key.jump").setDefault(InputDevice.keyboard, KEY_SPACE);
-	public @NotNull KeyBinding keyInventory = new KeyBinding("key.inventory").setDefault(InputDevice.keyboard, KEY_E);
-	public @NotNull KeyBinding keyDrop = new KeyBinding("key.drop").setDefault(InputDevice.keyboard, KEY_Q);
-	public @NotNull KeyBinding keyChat = new KeyBinding("key.chat").setDefault(InputDevice.keyboard, KEY_T);
-	public @NotNull KeyBinding keyCommand = new KeyBinding("key.command").setDefault(InputDevice.keyboard, KEY_SLASH);
-	public @NotNull KeyBinding keyToggleFog = new KeyBinding("key.fog");
-	public @NotNull KeyBinding keyToggleGamma = new KeyBinding("key.gamma");
-	public @NotNull KeyBinding keySneak = new KeyBinding("key.sneak").setDefault(InputDevice.keyboard, KEY_LSHIFT);
-	public @NotNull KeyBinding keyFly = new KeyBinding("key.fly").setDefault(InputDevice.keyboard, KEY_LCONTROL);
-	public @NotNull KeyBinding keyGuidebook = new KeyBinding("key.guidebook").setDefault(InputDevice.keyboard, KEY_R);
-	public @NotNull KeyBinding keyDescription = new KeyBinding("key.description").setDefault(InputDevice.keyboard, KEY_LCONTROL);
-	public @NotNull KeyBinding keyShowRecipe = new KeyBinding("key.showRecipe").setDefault(InputDevice.keyboard, KEY_R);
-	public @NotNull KeyBinding keyShowUsage = new KeyBinding("key.showUsage").setDefault(InputDevice.keyboard, KEY_U);
-	public @NotNull KeyBinding keyHotBarLeft = new KeyBinding("key.hotbar.left").setDefault(InputDevice.keyboard, KEY_COMMA);
-	public @NotNull KeyBinding keyHotBarRight = new KeyBinding("key.hotbar.right").setDefault(InputDevice.keyboard, KEY_PERIOD);
-	public @NotNull KeyBinding keyHotBarSwitch = new KeyBinding("key.hotbar.switch").setDefault(InputDevice.keyboard, KEY_TAB);
-
-	public @NotNull KeyBinding keyHideGui = new KeyBinding("key.immersiveMode").setDefault(InputDevice.keyboard, KEY_F1);
-	public @NotNull KeyBinding keyScreenshot = new KeyBinding("key.screenshot").setDefault(InputDevice.keyboard, KEY_F2);
-	public @NotNull KeyBinding keyToggleDebug = new KeyBinding("key.toggleDebug").setDefault(InputDevice.keyboard, KEY_F3);
-	public @NotNull KeyBinding keyToggleOverlay = new KeyBinding("key.toggleOverlay").setDefault(InputDevice.keyboard, KEY_F4);
-	public @NotNull KeyBinding keySwitchPerspective = new KeyBinding("key.switchPerspective").setDefault(InputDevice.keyboard, KEY_F5);
-	public @NotNull KeyBinding keyCinematicCamera = new KeyBinding("key.cinematicCamera").setDefault(InputDevice.keyboard, KEY_F8);
-	public @NotNull KeyBinding keyFullScreen = new KeyBinding("key.fullscreen").setDefault(InputDevice.keyboard, KEY_F11);
-	public @NotNull KeyBinding keyReleaseCursor = new KeyBinding("key.debug.releasecursor").setDefault(InputDevice.keyboard, KEY_F12);
-
-	public @NotNull KeyBinding keyHotBarSlot1 = new KeyBinding("key.hotbar.1").setDefault(InputDevice.keyboard, KEY_1);
-	public @NotNull KeyBinding keyHotBarSlot2 = new KeyBinding("key.hotbar.2").setDefault(InputDevice.keyboard, KEY_2);
-	public @NotNull KeyBinding keyHotBarSlot3 = new KeyBinding("key.hotbar.3").setDefault(InputDevice.keyboard, KEY_3);
-	public @NotNull KeyBinding keyHotBarSlot4 = new KeyBinding("key.hotbar.4").setDefault(InputDevice.keyboard, KEY_4);
-	public @NotNull KeyBinding keyHotBarSlot5 = new KeyBinding("key.hotbar.5").setDefault(InputDevice.keyboard, KEY_5);
-	public @NotNull KeyBinding keyHotBarSlot6 = new KeyBinding("key.hotbar.6").setDefault(InputDevice.keyboard, KEY_6);
-	public @NotNull KeyBinding keyHotBarSlot7 = new KeyBinding("key.hotbar.7").setDefault(InputDevice.keyboard, KEY_7);
-	public @NotNull KeyBinding keyHotBarSlot8 = new KeyBinding("key.hotbar.8").setDefault(InputDevice.keyboard, KEY_8);
-	public @NotNull KeyBinding keyHotBarSlot9 = new KeyBinding("key.hotbar.9").setDefault(InputDevice.keyboard, KEY_9);
-
-	public @NotNull KeyBinding keyLookLeft = new KeyBinding("key.look.left").setDefault(InputDevice.keyboard, KEY_LEFT);
-	public @NotNull KeyBinding keyLookRight = new KeyBinding("key.look.right").setDefault(InputDevice.keyboard, KEY_RIGHT);
-	public @NotNull KeyBinding keyLookUp = new KeyBinding("key.look.up").setDefault(InputDevice.keyboard, KEY_UP);
-	public @NotNull KeyBinding keyLookDown = new KeyBinding("key.look.down").setDefault(InputDevice.keyboard, KEY_DOWN);
-	public @NotNull KeyBinding keyCenterView = new KeyBinding("key.look.center").setDefault(InputDevice.keyboard, KEY_END);
-	public @NotNull KeyBinding keyZoom = new KeyBinding("key.zoom").setDefault(InputDevice.keyboard, KEY_C);
-	public @NotNull KeyBinding keyPlayerList = new KeyBinding("key.playerList").setDefault(InputDevice.keyboard, KEY_L);
-	public @NotNull KeyBinding keyPhotoMode = new KeyBinding("key.photoMode").setDefault(InputDevice.keyboard, KEY_P);
-	public @NotNull KeyBinding keyLockRotation = new KeyBinding("key.lockRotation").setDefault(InputDevice.keyboard, KEY_Z);
-	public @NotNull KeyBinding keyAutoWalk = new KeyBinding("key.autoWalk");
-	public @NotNull KeyBinding keyEasyBridge = new KeyBinding("key.easyBridge");
-	public @NotNull KeyBinding keySprint = new KeyBinding("key.sprint");
-	public @NotNull KeyBinding keyOpenAchievements = new KeyBinding("key.openAchievements");
-	public @NotNull KeyBinding keyOpenStatistics = new KeyBinding("key.openStatistics");
-	public @NotNull KeyBinding keyShowConsole = new KeyBinding("key.showConsole").setDefault(InputDevice.keyboard, KEY_GRAVE);
-	public @NotNull List<KeyBinding> debugsKeys = new ArrayList<>();
-	public @NotNull KeyBinding keyReload = new KeyBinding("key.debug.reload").setDefault(InputDevice.keyboard, KEY_R);
-	public @NotNull KeyBinding keySwitchGamemode = new KeyBinding("key.debug.gamemode").setDefault(InputDevice.keyboard, KEY_N);
-	public @NotNull KeyBinding keyDumpTextures = new KeyBinding("key.debug.dumptextures").setDefault(InputDevice.keyboard, KEY_D);
-	public @NotNull KeyBinding keyFullbright = new KeyBinding("key.debug.fullbright").setDefault(InputDevice.keyboard, KEY_F);
-	public @NotNull KeyBinding keyLightmaps = new KeyBinding("key.debug.lightmap").setDefault(InputDevice.keyboard, KEY_L);
-	public @NotNull KeyBinding keyCollisionBoxes = new KeyBinding("key.debug.collision").setDefault(InputDevice.keyboard, KEY_B);
-	public @NotNull KeyBinding keyChunkBorders = new KeyBinding("key.debug.chunkborders").setDefault(InputDevice.keyboard, KEY_G);
-	public @NotNull KeyBinding keyClearChat = new KeyBinding("key.debug.clearchat").setDefault(InputDevice.keyboard, KEY_C);
-	public @NotNull KeyBinding keyPauseLostFocus = new KeyBinding("key.debug.pauseFocus").setDefault(InputDevice.keyboard, KEY_P);
-	public @NotNull KeyBinding keyToggleItemInfo = new KeyBinding("key.debug.iteminfo").setDefault(InputDevice.keyboard, KEY_H);
-	public @NotNull KeyBinding keyReloadChunks = new KeyBinding("key.debug.reloadchunks").setDefault(InputDevice.keyboard, KEY_A);
-	public @NotNull KeyBinding keySmoothLighting = new KeyBinding("key.debug.smoothlighting").setDefault(InputDevice.keyboard, KEY_S);
-	public @NotNull KeyBinding keyShowShortcuts = new KeyBinding("key.debug.shortcuts").setDefault(InputDevice.keyboard, KEY_Q);
-	public @NotNull KeyBinding keyToggleTextureAtlas = new KeyBinding("key.debug.textureAtlas");
-	public @NotNull KeyBinding keyLoadChunksQuickly = new KeyBinding("key.debug.loadChunksQuickly");
-
-	public static final @NotNull List<@NotNull KeyBinding> keys = new ArrayList<>();
-	public static final @NotNull List<@NotNull Option<?>> options = new ArrayList<>();
-	public @NotNull List<@NotNull Option<?>> getAllOptions(){
-		return options;
-	}
-	
-	public KeyBinding getKey(int i) {
-		return keys.get(i);
-	}
-
-	public String getKeyBindName(int id) {
-		return I18n.getInstance().translateKey(getKey(id).getId());
-	}
-	
-	public GameSettings(Minecraft minecraft, File file) {
-		mc = minecraft;
-		optionsFile = new File(file, "options.txt");
-
-		debugsKeys.add(keyShowShortcuts);
-		debugsKeys.add(keyReload);
-		debugsKeys.add(keySwitchGamemode);
-		debugsKeys.add(keyDumpTextures);
-		debugsKeys.add(keyFullbright);
-		debugsKeys.add(keyLightmaps);
-		debugsKeys.add(keyCollisionBoxes);
-		debugsKeys.add(keyChunkBorders);
-		debugsKeys.add(keyClearChat);
-		debugsKeys.add(keyPauseLostFocus);
-		debugsKeys.add(keyToggleItemInfo);
-		debugsKeys.add(keyReloadChunks);
-		debugsKeys.add(keySmoothLighting);
-	}
-
-	public void init() {
-		loadOptions();
-		saveOptions();
-	}
-
-	public @NotNull String getDisplayString(Option<?> option) {
-		if (option == null) return "";
-		I18n trans = I18n.getInstance();
-		if (option instanceof OptionFloat) {
-			OptionFloat optionFloat = (OptionFloat) option;
-			float value = optionFloat.value;
-			if (option == brightness) {
-				int percent = (int)(value * 200.0f);
-				if (percent == 0) {
-					return trans.translateKey("options.brightness.min");
-				}else if (percent == 100) {
-					return trans.translateKey("options.brightness.default");
-				}else if (percent == 200) {
-					return trans.translateKey("options.brightness.max");
-				}else {
-					return percent + "%";
-				}
-			}
-			if (option == mouseSensitivity) {
-				if (value == 0.0F) {
-					return trans.translateKey("options.mouseSensitivity.min");
-				}
-				if (value == 1.0F) {
-					return trans.translateKey("options.mouseSensitivity.max");
-				} else {
-					return (int) (value * 200F) + "%";
-				}
-			}
-			if (option == FoV) {
-				if (value == 0) {
-					return trans.translateKey("options.fov.min");
-				}
-				if (value == 1) {
-					return trans.translateKey("options.fov.max");
-				} else {
-					return (int) (value * 100 + 30) + "°";
-				}
-			}
-			if (option == screenPadding) {
-				int percent = (int) (value * 100);
-				return percent + "%";
-			}
-			if (option == gamma) {
-				int percent = (int) (value * 200);
-				return percent + "%";
-			}
-			if (option == autosaveTimer) {
-				int timer = (int) (value * 24);
-				if (timer == 0) {
-					return trans.translateKey("options.autosaveTimer.off");
-				} else {
-					return (timer * 5) + " seconds";
-				}
-			}
-			if (option == cloudHeight) {
-				int percent = (int)(value * 100.0f + 100.0f);
-				if (percent == 100) {
-					return trans.translateKey("options.cloudHeight.default");
-				} else {
-					return percent + "%";
-				}
-			}
-			if (option == entityRenderDistance) {
-				int percent = MathHelper.round(value * 100.0f);
-				if (percent == 100) {
-					return trans.translateKey("options.entityRenderDistance.default");
-				} else {
-					return percent + "%";
-				}
-			}
-			if (value == 0.0F) {
-				return trans.translateKey("options.off");
-			} else {
-				return (int) (value * 100F) + "%";
-			}
-		}
-		if (option == guiScale) {
-			if (guiScale.value == 0) {
-				return trans.translateKey("options.guiScale.auto");
-			} else {
-				return guiScale.value + "x";
-			}
-		}
-		if(option == customFpsLimit){
-			int value = customFpsLimit.value;
-			int maxValue = 300;
-			if (enableVsync.value){
-				return String.valueOf(mc.gameWindow.getFrequency());
-			}
-			if(value > maxValue){
-				customFpsLimit.set(maxValue);
-			}
-			if(value < 15){
-				customFpsLimit.set(0);
-				return trans.translateKey("options.customFpsLimit.unlimited");
-			}
-		}
-		if (option == animations) {
-			return trans.translateKey(ANIMATIONS[animations.value]);
-		}
-		if (option == fancyGraphics) {
-			if (fancyGraphics.value == 1) {
-				return trans.translateKey("options.graphics.fancy");
-			} else {
-				return trans.translateKey("options.graphics.fast");
-			}
-		}
-		if (option == lightmapStyle) {
-			return trans.translateKey(lightmapStyle.value.getTranslationKey());
-		}
-		if(option == bloom) {
-			if(bloom.value == 0) {
-				return trans.translateKey("options.off");
-			}else if(bloom.value == 1) {
-				return trans.translateKey("options.bloom.low");
-			}else if(bloom.value == 2) {
-				return trans.translateKey("options.bloom.high");
-			}
-		}
-		if (option == this.tooltipStyle) {
-			TooltipElement.Style style = TooltipElement.styleMap.get(this.tooltipStyle.value);
-			if (style != null) {
-				return trans.translateKey(style.translationKey);
-			}
-			return "Unknown";
-		}
-		if (option == this.font) {
-			return trans.translateKey("options.font." + this.font.value.getKey());
-		}
-		if (option instanceof OptionBoolean) {
-			Boolean flag = (Boolean) option.value;
-			if (flag) {
-				return trans.translateKey("options.on");
-			} else {
-				return trans.translateKey("options.off");
-			}
-		}
-		if(option instanceof OptionEnum<?>) {
-			OptionEnum<?> optionEnum = (OptionEnum<?>) option;
-			
-			String key;
-			
-			if(optionEnum.value instanceof ITranslatable) {
-				ITranslatable translatable = (ITranslatable) optionEnum.value;
-				
-				key = translatable.getTranslationKey();
-			}else {
-				key = optionEnum.value.toString().toLowerCase();
-			}
-			
-			return trans.translateKey("options." + optionEnum.name+"." + key);
-		}
-		return emptyStringIfNull(option.value.toString());
-	}
-
-	public void optionChanged(Option<?> option) {
-		if (option == null) return;
-		if (option == difficulty) {
-			if (mc.currentWorld != null) {
-				mc.currentWorld.setDifficulty(difficulty.value, false);
-			}
-		}
-		if(option == renderDistance) {
-			if (mc.currentScreen instanceof ScreenOptions) {
-				ScreenOptions.queueReload = true;
-			} else {
-				mc.renderGlobal.allChanged();
-			}
-		}
-
-		if(option == playerLeftHanded && mc.thePlayer != null) {mc.thePlayer.playerConfig.setLeftHand(playerLeftHanded.value);}
-		if(option == playerCape && mc.thePlayer != null) {mc.thePlayer.playerConfig.setCape(playerCape.value);}
-		if(option == playerHat && mc.thePlayer != null) {mc.thePlayer.playerConfig.setHat(playerHat.value);}
-		if(option == playerJacket && mc.thePlayer != null) {mc.thePlayer.playerConfig.setJacket(playerJacket.value);}
-		if(option == playerSleeveLeft && mc.thePlayer != null) {mc.thePlayer.playerConfig.setSleeveLeft(playerSleeveLeft.value);}
-		if(option == playerSleeveRight && mc.thePlayer != null) {mc.thePlayer.playerConfig.setSleeveRight(playerSleeveRight.value);}
-		if(option == playerPantLeft && mc.thePlayer != null) {mc.thePlayer.playerConfig.setPantLeft(playerPantLeft.value);}
-		if(option == playerPantRight && mc.thePlayer != null) {mc.thePlayer.playerConfig.setPantRight(playerPantRight.value);}
-		if(option == playerDevModel && mc.thePlayer != null) {mc.thePlayer.playerConfig.setDevModelEnabled(playerDevModel.value);}
-		if(option == playerHurtSound && mc.thePlayer != null) {mc.thePlayer.playerConfig.setHurtSound(playerHurtSound.value);}
-
-		if(option == enableVsync) mc.gameWindow.setVsync(enableVsync.value);
-		if(option == fancyGraphics) mc.renderGlobal.allChanged();
-		if(option == ambientOcclusion) mc.renderGlobal.allChanged();
-		if(option == connectedGlass) mc.renderGlobal.allChanged();
-//		if(option == advancedOpenGL) mc.renderGlobal.allChanged();
-		if(option == biomeWater) {
-			mc.renderGlobal.allChanged();
-			mc.textureManager.updateDynamicTextures(false);
-		}
-		if(option == treeShadows) mc.renderGlobal.allChanged();
-		if(option == placementMode && mc.thePlayer != null) mc.thePlayer.syncPlacementMode();
-		if(option == animations || option == customAnimations) {
-			mc.textureManager.refreshTexturesAndDisplayErrors();
-			mc.textureManager.updateDynamicTextures(false);
-			mc.renderGlobal.allChanged();
-		}
-		if(option == fullscreen) mc.gameWindow.updateWindowState();
-		if(option == borderlessFullscreen && fullscreen.value) mc.gameWindow.updateWindowState();
-		if(option == guiScale) {
-			int max = mc.resolution.getMaxScale(mc.gameWindow.getWidthScreenCoords(), mc.gameWindow.getHeightScreenCoords());
-			guiScale.value = (guiScale.value + max) % max;
-			mc.resolution.setScale(guiScale.value);
-			if (mc.currentScreen != null) {
-				mc.currentScreen.opened(mc.resolution.getScaledWidthScreenCoords(), mc.resolution.getScaledHeightScreenCoords());
-			}
-		}
-		if(option == mipmapType || option == mipmapLevels) {
-			mc.textureManager.refreshTexturesAndDisplayErrors();
-		}
-		if(option == autosaveTimer) {
-			int max = 24;
-			autosaveTimer.value = (autosaveTimer.value + max) % max;
-		}
-		if(option == discordRichPresence)
-		{
-			if (discordRichPresence.value && mc.rpcThread == null)
-			{
-				mc.rpcThread = new RichPresenceHandlerThread(mc);
-				mc.rpcThread.setName("Discord RPC Thread");
-				mc.rpcThread.start();
-			}
-		}
-		if(option == language) {
-			if (mc.currentScreen != null) {
-				mc.currentScreen.opened(mc.resolution.getScaledWidthScreenCoords(), mc.resolution.getScaledHeightScreenCoords());
-			}
-		}
-		if(option == customLightmap) {
-			mc.worldRenderer.lightmapHelper.setup();
-		}
-		if(option == rawMouseInput) {
-			mc.mouseInput.setRawInput(rawMouseInput.value);
-		}
-		if(option == enableHolidayTextures) {
-			mc.textureManager.refreshTexturesAndDisplayErrors();
-			mc.renderGlobal.allChanged();
-		}
-		if(option == musicFrequency) {
-			mc.sndManager.resetMusicTicks();
-		}
-	}
-
-	public void loadOptions() {
-		HudComponents.DEFAULT_LAYOUT = HudComponents.INSTANCE.toSettingsString();
-		if (!optionsFile.exists()) return;
-		try {
-			BufferedReader br = new BufferedReader(new FileReader(optionsFile));
-			
-line:		for (String line; (line = br.readLine()) != null;) {
-				try {
-					int i = line.indexOf(':');
-					String key = line.substring(0, i);
-					String value = line.substring(i + 1);
-					
-					if (key.equals("hudLayout")) {
-						HudComponents.INSTANCE.fromSettingsString(value);
-						continue line;
-					}
-					
-					for(Option<?> option : getAllOptions()) {
-						if(option.name.equalsIgnoreCase(key)) {
-							option.parse(value);
-							continue line;
-						}
-					}
-
-                    for (KeyBinding keyBinding : keys) {
-                        if (key.equals("key_" + keyBinding.getId())) {
-                            keyBinding.fromOptionsString(value);
-                            continue line;
-                        }
-                    }
-				} catch (Exception e) {
-                    LOGGER.warn("Skipping bad option: {}", line, e);
-				}
-			}
-
-			br.close();
-		} catch (Exception e) {
-			LOGGER.error("Failed to load options", e);
-		}
-	}
-	
-	public void saveOptions() {
-		try {
-			PrintWriter printwriter = new PrintWriter(new FileWriter(optionsFile));
-			
-			for(Option<?> option : getAllOptions()) {
-				printwriter.println(option.name+":"+option.getValueString());
-			}
-			
-			for (KeyBinding key : keys) {
-				printwriter.println("key_" + key.getId() + ":" + key.toOptionsString());
-			}
-
-			String hudComponentsString = HudComponents.INSTANCE.toSettingsString();
-			if(hudComponentsString != null) {
-				printwriter.println("hudLayout:" + hudComponentsString);
-			}
-
-			printwriter.close();
-		} catch (Exception exception) {
-			LOGGER.error("Failed to save options", exception);
-		}
-	}
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static org.lwjgl.input.Keyboard.KEY_1;
+import static org.lwjgl.input.Keyboard.KEY_2;
+import static org.lwjgl.input.Keyboard.KEY_3;
+import static org.lwjgl.input.Keyboard.KEY_4;
+import static org.lwjgl.input.Keyboard.KEY_5;
+import static org.lwjgl.input.Keyboard.KEY_6;
+import static org.lwjgl.input.Keyboard.KEY_7;
+import static org.lwjgl.input.Keyboard.KEY_8;
+import static org.lwjgl.input.Keyboard.KEY_9;
+import static org.lwjgl.input.Keyboard.KEY_A;
+import static org.lwjgl.input.Keyboard.KEY_B;
+import static org.lwjgl.input.Keyboard.KEY_C;
+import static org.lwjgl.input.Keyboard.KEY_COMMA;
+import static org.lwjgl.input.Keyboard.KEY_D;
+import static org.lwjgl.input.Keyboard.KEY_DOWN;
+import static org.lwjgl.input.Keyboard.KEY_E;
+import static org.lwjgl.input.Keyboard.KEY_END;
+import static org.lwjgl.input.Keyboard.KEY_F;
+import static org.lwjgl.input.Keyboard.KEY_F1;
+import static org.lwjgl.input.Keyboard.KEY_F11;
+import static org.lwjgl.input.Keyboard.KEY_F12;
+import static org.lwjgl.input.Keyboard.KEY_F2;
+import static org.lwjgl.input.Keyboard.KEY_F3;
+import static org.lwjgl.input.Keyboard.KEY_F4;
+import static org.lwjgl.input.Keyboard.KEY_F5;
+import static org.lwjgl.input.Keyboard.KEY_F8;
+import static org.lwjgl.input.Keyboard.KEY_G;
+import static org.lwjgl.input.Keyboard.KEY_GRAVE;
+import static org.lwjgl.input.Keyboard.KEY_H;
+import static org.lwjgl.input.Keyboard.KEY_L;
+import static org.lwjgl.input.Keyboard.KEY_LCONTROL;
+import static org.lwjgl.input.Keyboard.KEY_LSHIFT;
+import static org.lwjgl.input.Keyboard.KEY_N;
+import static org.lwjgl.input.Keyboard.KEY_P;
+import static org.lwjgl.input.Keyboard.KEY_PERIOD;
+import static org.lwjgl.input.Keyboard.KEY_Q;
+import static org.lwjgl.input.Keyboard.KEY_R;
+import static org.lwjgl.input.Keyboard.KEY_S;
+import static org.lwjgl.input.Keyboard.KEY_SLASH;
+import static org.lwjgl.input.Keyboard.KEY_SPACE;
+import static org.lwjgl.input.Keyboard.KEY_T;
+import static org.lwjgl.input.Keyboard.KEY_TAB;
+import static org.lwjgl.input.Keyboard.KEY_U;
+import static org.lwjgl.input.Keyboard.KEY_UP;
+import static org.lwjgl.input.Keyboard.KEY_W;
+import static org.lwjgl.input.Keyboard.KEY_Z;
+
+public final class GameSettings {
+    private static final @NotNull Logger LOGGER = LogUtils.getLogger();
+
+    private static final @NotNull Map<@NotNull String, @NotNull String> savedValues = new Object2ObjectOpenHashMap<>();
+
+    private static final @NotNull Map<@NotNull String, @NotNull Option<?>> registeredOptions = new Object2ObjectOpenHashMap<>();
+    private static final @NotNull Map<@NotNull String, @NotNull KeyBinding> registeredKeys = new Object2ObjectOpenHashMap<>();
+    private static final @NotNull List<@NotNull Option<?>> allOptions = new ObjectArrayList<>();
+    private static final @NotNull List<@NotNull KeyBinding> allKeys = new ObjectArrayList<>();
+
+    public static @NotNull Collection<@NotNull Option<?>> getAllOptions() {
+        return allOptions;
+    }
+
+    public static @Nullable Option<?> getOption(@NotNull String id) {
+        return registeredOptions.get(id);
+    }
+
+    public static @NotNull Collection<@NotNull KeyBinding> getAllKeys() {
+        return allKeys;
+    }
+
+    public static @Nullable KeyBinding getKeyBinding(@NotNull String id) {
+        return registeredKeys.get(id);
+    }
+
+    public static final @NotNull OptionInteger WINDOW_WIDTH = register(new OptionInteger("windowWidth", 854));
+    public static final @NotNull OptionInteger WINDOW_HEIGHT = register(new OptionInteger("windowHeight", 480));
+
+    public static final @NotNull OptionVolume MASTER_VOLUME = register(new OptionVolume("sound.master", 1.0f, SoundCategory.GUI_SOUNDS));
+    public static final @NotNull OptionVolume MUSIC_VOLUME = register(new OptionVolume("sound.music", 1.0f, SoundCategory.MUSIC));
+    public static final @NotNull OptionVolume WORLD_SOUNDS_VOLUME = register(new OptionVolume("sound.world", 1.0f, SoundCategory.WORLD_SOUNDS));
+    public static final @NotNull OptionVolume ENTITY_SOUNDS_VOLUME = register(new OptionVolume("sound.entity", 1.0f, SoundCategory.ENTITY_SOUNDS));
+    public static final @NotNull OptionVolume CAVE_SOUNDS_VOLUME = register(new OptionVolume("sound.cave", 1.0f, SoundCategory.CAVE_SOUNDS));
+    public static final @NotNull OptionVolume GUI_SOUNDS_VOLUME = register(new OptionVolume("sound.gui", 1.0f, SoundCategory.GUI_SOUNDS));
+    public static final @NotNull OptionVolume WEATHER_SOUNDS_VOLUME = register(new OptionVolume("sound.weather", 1.0f, SoundCategory.WEATHER_SOUNDS));
+    public static final @NotNull OptionBoolean PLAY_TITLE_SCREEN_MUSIC = register(new OptionBoolean("playTitleScreenMusic", false));
+
+    public static final @NotNull OptionFloat FOV = register(new OptionFloat("fov", 0.40140846f)
+        .withDisplayStringProvider((mc, i18n, option) -> {
+            if (option.value == 0) {
+                return i18n.translateKey("options.fov.min");
+            }
+            if (option.value == 1) {
+                return i18n.translateKey("options.fov.max");
+            } else {
+                return (int) (option.value * 100 + 30) + "°";
+            }
+        }));
+    public static final @NotNull OptionFloat MOUSE_SENSITIVITY = register(new OptionFloat("mouseSensitivity", 0.5f)
+        .withDisplayStringProvider((mc, i18n, option) -> {
+            if (option.value == 0.0F) {
+                return i18n.translateKey("options.mouseSensitivity.min");
+            }
+            if (option.value == 1.0F) {
+                return i18n.translateKey("options.mouseSensitivity.max");
+            } else {
+                return (int) (option.value * 200F) + "%";
+            }
+        }));
+    public static final @NotNull OptionFloat SCREEN_PADDING = register(new OptionFloat("screenPadding", 0.0f)
+        .withDisplayStringProvider((mc, i18n, option) -> {
+            int percent = (int) (option.value * 100);
+            return percent + "%";
+        }));
+    public static final @NotNull OptionFloat GAMMA = register(new OptionFloat("gamma", 0.5f)
+        .withDisplayStringProvider((mc, i18n, option) -> {
+            int percent = (int) (option.value * 200);
+            return percent + "%";
+        }));
+    public static final @NotNull OptionFloat BRIGHTNESS = register(new OptionFloat("brightness", 0.5f)
+        .withDisplayStringProvider((mc, i18n, option) -> {
+            int percent = (int) (option.value * 200.0f);
+            if (percent == 0) {
+                return i18n.translateKey("options.brightness.min");
+            } else if (percent == 100) {
+                return i18n.translateKey("options.brightness.default");
+            } else if (percent == 200) {
+                return i18n.translateKey("options.brightness.max");
+            } else {
+                return percent + "%";
+            }
+        }));
+
+    public static final @NotNull OptionFloat FXAA = register(new OptionFloat("fxaa", 0.0f));
+    public static final @NotNull OptionFloat CONTROLLER_SENSITIVITY = register(new OptionFloat("controllerSensitivity", 0.5f));
+    public static final @NotNull OptionFloat CONTROLLER_MENU_SENSITIVITY = register(new OptionFloat("controllerMenuSensitivity", 0.5f));
+    public static final @NotNull OptionFloat CONTROLLER_DEADZONE_LEFT = register(new OptionFloat("controllerDeadzoneL", 0.25f));
+    public static final @NotNull OptionFloat CONTROLLER_DEADZONE_RIGHT = register(new OptionFloat("controllerDeadzoneR", 0.25f));
+    public static final @NotNull OptionFloat BLOCK_OUTLINE_WIDTH = register(new OptionFloat("blockOutlineWidth", 0.25f));
+
+    public static final @NotNull OptionFloat FLIGHT_SPEED = register(new OptionFloat("flightSpeed", 0.5f));
+    public static final @NotNull OptionFloat FLIGHT_SMOOTHNESS = register(new OptionFloat("flightSmoothness", 0.5f));
+
+    public static final @NotNull OptionBoolean INVERT_MOUSE = register(new OptionBoolean("invertYMouse", false));
+    public static final @NotNull OptionBoolean RAW_MOUSE_INPUT = register(new OptionBoolean("rawMouseInput", false)
+        .addOnChangeCallback((mc, option) -> mc.mouseInput.setRawInput(option.value)));
+    public static final @NotNull OptionBoolean VIEW_BOBBING = register(new OptionBoolean("bobView", true));
+    public static final @NotNull OptionBoolean TRANSPARENCY_DEPTH_CHECK = register(new OptionBoolean("transparencyDepthCheck", true));
+    public static final @NotNull OptionEnum<ParticlesQuality> PARTICLES_QUALITY = register(new OptionEnum<>("particleQuality", ParticlesQuality.class, ParticlesQuality.ALL));
+    public static final @NotNull OptionRange PARTICLES_CAP = register(new OptionRange("particleCap", 4000, 500, 15000));
+    public static final @NotNull OptionFloat PARTICLE_RENDER_DISTANCE = register(new OptionFloat("particleRenderDistance", 1f)
+        .withDisplayStringProvider((mc, i18n, option) -> {
+            int percent = MathHelper.round(option.value * 100.0f);
+            if (percent == 100) {
+                return i18n.translateKey("options.particleRenderDistance.default");
+            } else {
+                return percent + "%";
+            }
+        }));
+    public static final @NotNull OptionRange CHUNK_REBUILDS_PER_FRAME = register(new OptionRange("chunkRebuilds", 6, 2, 12));
+    public static final @NotNull OptionBoolean FRUSTUM_CULLING = register(new OptionBoolean("frustumCulling", true));
+    public static final @NotNull OptionBoolean ENTITY_SHADOWS = register(new OptionBoolean("entityShadows", true));
+    public static final @NotNull OptionEnum<TextOutlineQuality> TEXT_OUTLINE_QUALITY = register(new OptionEnum<>("textOutlineQuality", TextOutlineQuality.class, TextOutlineQuality.FANCY));
+    public static final @NotNull OptionEnum<CloudQuality> CLOUD_QUALITY = register(new OptionEnum<>("cloudQuality", CloudQuality.class, CloudQuality.FANCY));
+    public static final @NotNull OptionEnum<LeavesQuality> LEAVES_QUALITY = register(new OptionEnum<>("leavesQuality", LeavesQuality.class, LeavesQuality.FANCY)
+        .addOnChangeCallback((mc, option) -> mc.renderGlobal.allChanged()));
+    public static final @NotNull OptionBoolean TREE_SHADOWS = register(new OptionBoolean("treeShadows", true)
+        .addOnChangeCallback((mc, option) -> mc.renderGlobal.allChanged()));
+    public static final @NotNull OptionBoolean CONNECTED_GLASS = register(new OptionBoolean("connectedGlass", false)
+        .addOnChangeCallback((mc, option) -> mc.renderGlobal.allChanged()));
+    public static final @NotNull OptionBoolean AMBIENT_OCCLUSION = register(new OptionBoolean("ambientOcclusion", true)
+        .addOnChangeCallback((mc, option) -> mc.renderGlobal.allChanged()));
+    public static final @NotNull OptionBoolean ITEMS_3D = register(new OptionBoolean("3Ditems", false));
+    public static final @NotNull OptionBoolean SMOOTH_CAMERA = register(new OptionBoolean("smoothCamera", false));
+    public static final @NotNull OptionBoolean LOCK_CAMERA = register(new OptionBoolean("lockCamera", false));
+    public static final @NotNull OptionBoolean BIOME_WATER = register(new OptionBoolean("biomeWater", true)
+        .addOnChangeCallback((mc, option) -> {
+            mc.textureManager.updateDynamicTextures(false);
+            mc.renderGlobal.allChanged();
+        }));
+    public static final @NotNull OptionBoolean VIGNETTE = register(new OptionBoolean("vignette", true));
+    public static final @NotNull OptionBoolean SHOW_PLAYER_LIST = register(new OptionBoolean("showPlayerList", false));
+    public static final @NotNull OptionBoolean SLIME_PARTICLES = register(new OptionBoolean("slimeParticles", true));
+    public static final @NotNull OptionString SHADER_OVERRIDE = register(new OptionString("shaderOverride", ""));
+    public static final @NotNull OptionBoolean AUTO_HIT = register(new OptionBoolean("autoHit", true));
+    public static final @NotNull OptionBoolean EASY_BRIDGE = register(new OptionBoolean("easyBridge", true));
+    public static final @NotNull OptionBoolean FOOD_HEALTH_REGEN_OVERLAY = register(new OptionBoolean("foodHealthRegenOverlay", true));
+    public static final @NotNull OptionBoolean FPS_IN_OVERLAY = register(new OptionBoolean("fpsInOverlay", false));
+    public static final @NotNull OptionBoolean VERSION_IN_OVERLAY = register(new OptionBoolean("versionInOverlay", false));
+    public static final @NotNull OptionBoolean CONTROLLER_SWAP_SHOULDER_BUTTONS = register(new OptionBoolean("controllerSwapShoulderButtons", false));
+    public static final @NotNull OptionBoolean CONTROLLER_SWAP_AB = register(new OptionBoolean("controllerSwapAB", false));
+    public static final @NotNull OptionBoolean CONTROLLER_SWAP_XY = register(new OptionBoolean("controllerSwapXY", false));
+    public static final @NotNull OptionBoolean CLOUDS = register(new OptionBoolean("clouds", true));
+    public static final @NotNull OptionFloat CLOUD_HEIGHT = register(new OptionFloat("cloudHeight", 0f)
+        .withDisplayStringProvider((mc, i18n, option) -> {
+            int percent = (int) (option.value * 100.0f + 100.0f);
+            if (percent == 100) {
+                return i18n.translateKey("options.cloudHeight.default");
+            } else {
+                return percent + "%";
+            }
+        }));
+    public static final @NotNull OptionFloat ENTITY_RENDER_DISTANCE = register(new OptionFloat("entityRenderDistance", 1f)
+        .withDisplayStringProvider((mc, i18n, option) -> {
+            int percent = MathHelper.round(option.value * 100.0f);
+            if (percent == 100) {
+                return i18n.translateKey("options.entityRenderDistance.default");
+            } else {
+                return percent + "%";
+            }
+        }));
+    public static final @NotNull OptionBoolean ARMOR_DURABILITY_OVERLAY = register(new OptionBoolean("armorDurabilityOverlay", false));
+    public static final @NotNull OptionBoolean ARMOR_PROTECTION_OVERLAY = register(new OptionBoolean("armorProtectionOverlay", true));
+    public static final @NotNull OptionBoolean HELD_ITEM_COUNT_OVERLAY = register(new OptionBoolean("heldItemCountOverlay", false));
+    public static final @NotNull OptionBoolean PAUSE_ON_LOST_FOCUS = register(new OptionBoolean("pauseOnLostFocus", true));
+    public static final @NotNull OptionBoolean SHOW_DEBUG_SCREEN = register(new OptionBoolean("showDebugScreen", false));
+    public static final @NotNull OptionBoolean SHOW_FRAME_TIMES = register(new OptionBoolean("showFrameTimes", false));
+    public static final @NotNull OptionBoolean SHOW_ITEM_DEBUG_INFO = register(new OptionBoolean("showItemDebugInfo", false));
+    public static final @NotNull OptionBoolean SHOW_CHUNK_BORDERS = register(new OptionBoolean("showChunkBorders", false));
+    public static final @NotNull OptionBoolean SHOW_COLLISION_BOXES = register(new OptionBoolean("showCollisionBoxes", false));
+    public static final @NotNull OptionBoolean SWAP_CRAFTING_BUTTONS = register(new OptionBoolean("swapCraftingButtons", false));
+    public static final @NotNull OptionBoolean FORCE_ONSCREEN_KEYBOARD = register(new OptionBoolean("forceOnscreenKeyboard", false));
+    public static final @NotNull OptionEnum<PlacementMode> PLACEMENT_MODE = register(new OptionEnum<>("placementMode", PlacementMode.class, PlacementMode.DEFAULT).setIsSlider(false)
+        .addOnChangeCallback((mc, option) -> {
+            if (mc.thePlayer != null) mc.thePlayer.syncPlacementMode();
+        }));
+    public static final @NotNull OptionBoolean DISCORD_RICH_PRESENCE = register(new OptionBoolean("discordRichPresence", false)
+        .addOnChangeCallback((mc, option) -> {
+            if (option.value && mc.rpcThread == null) {
+                mc.rpcThread = new RichPresenceHandlerThread(mc);
+                mc.rpcThread.setName("Discord RPC Thread");
+                mc.rpcThread.start();
+            }
+        }));
+    public static final @NotNull OptionImmersiveMode IMMERSIVE_MODE = register(new OptionImmersiveMode());
+    public static final @NotNull OptionColor GUI_BACKGROUND_COLOR = register(new OptionColor("guiBackgroundColor", new Color().setARGB(0xc0101010)));
+    public static final @NotNull OptionEnum<Difficulty> DIFFICULTY = register(new OptionEnum<>("difficulty", Difficulty.class, Difficulty.NORMAL) // Stub for local difficulty setting
+        .addOnChangeCallback((mc, option) -> {
+            if (mc.currentWorld != null) {
+                mc.currentWorld.setDifficulty(option.value, false);
+            }
+        }));
+    public static final @NotNull OptionInteger THIRD_PERSON_VIEW = register(new OptionInteger("thirdPersonView", 0));
+    public static final @NotNull OptionRange RENDER_DISTANCE = register(new OptionRange("renderDistance", 12, 2, 32)
+        .addOnChangeCallback((mc, option) -> {
+            if (mc.currentScreen instanceof ScreenOptions) {
+                ScreenOptions.queueReload = true;
+            } else {
+                mc.renderGlobal.allChanged();
+            }
+        }));
+    public static final @NotNull OptionBoolean ENABLE_VSYNC = register(new OptionBoolean("enableVsync", false)
+        .addOnChangeCallback((mc, option) -> mc.gameWindow.setVsync(option.value)));
+    public static final @NotNull OptionEnum<ChatVisibility> chatVisibility = register(new OptionEnum<>("chatVisibility", ChatVisibility.class, ChatVisibility.SHOW_ALL));
+    public static final @NotNull OptionRange CUSTOM_FPS_LIMIT = register(new OptionRange("customFpsLimit", 165, 301)
+        .withDisplayStringProvider((mc, i18n, option) -> {
+            int value = option.value;
+            int maxValue = 300;
+            if (ENABLE_VSYNC.value) {
+                return String.valueOf(mc.gameWindow.getFrequency());
+            }
+            if (value > maxValue) {
+                option.set(maxValue);
+            }
+            if (value < 15) {
+                option.set(0);
+                return i18n.translateKey("options.customFpsLimit.unlimited");
+            }
+            return option.toOptionsString();
+        }));
+    public static final @NotNull OptionGuiScale GUI_SCALE = register(new OptionGuiScale("guiScale", 0)
+        .addOnChangeCallback((mc, option) -> {
+            int max = ScaledResolution.getMaxScale(mc.gameWindow.getWidthScreenCoords(), mc.gameWindow.getHeightScreenCoords());
+            option.value = (option.value + max) % max;
+            mc.resolution.setScale(option.value);
+            if (mc.currentScreen != null) {
+                mc.currentScreen.opened(mc.resolution.getScaledWidthScreenCoords(), mc.resolution.getScaledHeightScreenCoords());
+            }
+        })
+        .withDisplayStringProvider((mc, i18n, option) -> {
+            if (option.value == 0) {
+                return i18n.translateKey("options.guiScale.auto");
+            } else {
+                return option.value + "x";
+            }
+        }));
+    public static final @NotNull OptionInteger OVERLAY_MODE = register(new OptionInteger("overlayMode", 0));
+    public static final @NotNull OptionInteger ROTATION_OVERLAY_MODE = register(new OptionInteger("rotationOverlayMode", 0));
+    public static final @NotNull OptionEnum<TextureAnimation> TEXTURE_ANIMATIONS = register(new OptionEnum<>("animations", TextureAnimation.class, TextureAnimation.CUSTOM)
+        .addOnChangeCallback((mc, option) -> {
+            mc.textureManager.refreshTexturesAndDisplayErrors();
+            mc.textureManager.updateDynamicTextures(false);
+            mc.renderGlobal.allChanged();
+        }));
+    public static final @NotNull OptionBoolean CUSTOM_TEXTURE_ANIMATIONS = register(new OptionBoolean("customAnimations", true)
+        .addOnChangeCallback((mc, option) -> {
+            mc.textureManager.refreshTexturesAndDisplayErrors();
+            mc.textureManager.updateDynamicTextures(false);
+            mc.renderGlobal.allChanged();
+        }));
+    public static final @NotNull OptionInteger PLAYER_LIST_POSITION = register(new OptionInteger("playerListPosition", 2));
+    public static final @NotNull OptionBoolean HELD_ITEM_TOOLTIPS = register(new OptionBoolean("heldItemTooltips", true));
+    public static final @NotNull OptionFloat COLOR_CORRECTION = register(new OptionFloat("colorCorrection", 0.5f));
+    public static final @NotNull OptionBoolean SNEAK_TOGGLE = register(new OptionBoolean("sneakToggle", false));
+    public static final @NotNull OptionFloat AUTOSAVE_TIMER = register(new OptionFloat("autosaveTimer", 0.04166666666F)
+        .addOnChangeCallback((mc, option) -> {
+            int max = 24;
+            option.value = (option.value + max) % max;
+        })
+        .withDisplayStringProvider((mc, i18n, option) -> {
+            int timer = (int) (option.value * 24);
+            if (timer == 0) {
+                return i18n.translateKey("options.autosaveTimer.off");
+            } else {
+                return (timer * 5) + " seconds";
+            }
+        }));
+    public static final @NotNull OptionBoolean ENABLE_ITEM_DRAGGING = register(new OptionBoolean("enableItemDragging", true));
+    public static final @NotNull OptionRange BLOOM = register(new OptionRange("bloom", 0, 3)
+        .withDisplayStringProvider((mc, i18n, option) -> {
+            if (option.value == 0) {
+                return i18n.translateKey("options.off");
+            } else if (option.value == 1) {
+                return i18n.translateKey("options.bloom.low");
+            } else if (option.value == 2) {
+                return i18n.translateKey("options.bloom.high");
+            }
+            return option.toOptionsString();
+        }));
+    public static final @NotNull OptionEnum<RenderScale> RENDER_SCALE = register(new OptionEnum<>("renderScale", RenderScale.class, RenderScale.SCALE_100));
+    public static final @NotNull OptionBoolean HEAT_HAZE = register(new OptionBoolean("heatHaze", false));
+    public static final @NotNull OptionBoolean ALPHA_MENU = register(new OptionBoolean("old", false));
+    public static final @NotNull OptionBoolean ENABLE_ITEM_CLUMPING = register(new OptionBoolean("enableItemClumping", true));
+    public static final @NotNull OptionEnum<DescriptionPromptEnum> ITEM_DESCRIPTIONS = register(new OptionEnum<>("itemDescriptions", DescriptionPromptEnum.class, DescriptionPromptEnum.PROMPT));
+    public static final @NotNull OptionBoolean TURN_WITH_VEHICLE = register(new OptionBoolean("turnWithVehicle", true));
+    public static final @NotNull OptionBoolean DISABLE_CRASH_HANDLER = register(new OptionBoolean("disableCrashHandler", false));
+    public static final @NotNull OptionEnum<SelectedProvider> CHUNK_PROVIDER = register(new OptionEnum<>("enableThreadedChunkProvider", SelectedProvider.class, SelectedProvider.THREADED));
+    public static final @NotNull OptionBoolean MUSIC_TOASTS = register(new OptionBoolean("musicToasts", true));
+    public static final @NotNull OptionEnum<MusicFrequency> MUSIC_FREQUENCY = register(new OptionEnum<>("musicFrequency", MusicFrequency.class, MusicFrequency.DEFAULT)
+        .addOnChangeCallback((mc, option) -> mc.sndManager.resetMusicTicks()));
+
+    public static final @NotNull OptionBoolean ENABLE_DEV_RESOURCE_LOADING = register(new OptionBoolean("enableDevResourceLoading", false));
+    public static final @NotNull OptionBoolean DOWNLOAD_SOUNDFILES = register(new OptionBoolean("downloadSoundfiles", true));
+    public static final @NotNull OptionBoolean ALLOW_SOUND_OVERRIDES = register(new OptionBoolean("allowSoundOverrides", false));
+    public static final @NotNull OptionBoolean LOAD_ALL_SOUNDS = register(new OptionBoolean("loadAllSounds", false));
+
+    public static final @NotNull OptionBoolean OVERLAY_SHOW_COORDS = register(new OptionBoolean("overlayShowCoords", true));
+    public static final @NotNull OptionBoolean OVERLAY_SHOW_DIRECTION = register(new OptionBoolean("overlayShowDirection", true));
+    public static final @NotNull OptionBoolean OVERLAY_SHOW_TIME = register(new OptionBoolean("overlayShowTime", true));
+    public static final @NotNull OptionBoolean OVERLAY_SHOW_SEASON = register(new OptionBoolean("overlayShowSeason", true));
+    public static final @NotNull OptionBoolean OVERLAY_SHOW_WEATHER = register(new OptionBoolean("overlayShowWeather", true));
+    public static final @NotNull OptionBoolean OVERLAY_SHOW_BIOME = register(new OptionBoolean("overlayShowBiome", true));
+
+    public static final @NotNull OptionBoolean @NotNull [] OVERLAY_ELEMENTS = new OptionBoolean[]{OVERLAY_SHOW_COORDS, OVERLAY_SHOW_DIRECTION, OVERLAY_SHOW_TIME, OVERLAY_SHOW_SEASON, OVERLAY_SHOW_WEATHER, OVERLAY_SHOW_BIOME};
+
+    public static final @NotNull OptionString LAST_SERVER = register(new OptionString("lastServer", ""));
+    public static final @NotNull OptionString SKIN = register(new OptionString("skin", "Default"));
+    public static final @NotNull OptionString SELECTED_CONTROLLER = register(new OptionString("selectedController", ""));
+    public static final @NotNull OptionString LANGUAGE = register(new OptionString("language", "en_US")
+        .addOnChangeCallback((mc, option) -> {
+            if (mc.currentScreen != null) {
+                mc.currentScreen.opened(mc.resolution.getScaledWidthScreenCoords(), mc.resolution.getScaledHeightScreenCoords());
+            }
+        }));
+
+    public static final @NotNull OptionRange MIPMAP_LEVELS = register(new OptionRange("mipmapLevels", 0, 5)
+        .addOnChangeCallback((mc, option) -> mc.textureManager.refreshTexturesAndDisplayErrors()));
+    public static final @NotNull OptionEnum<MipmapType> MIPMAP_TYPE = register(new OptionEnum<>("mipmapType", MipmapType.class, MipmapType.SMOOTH)
+        .addOnChangeCallback((mc, option) -> mc.textureManager.refreshTexturesAndDisplayErrors()));
+
+    public static final @NotNull OptionBoolean FOV_MODIFICATION = register(new OptionBoolean("fov.modification", true));
+    public static final @NotNull OptionBoolean SCREEN_MOTION_EFFECTS = register(new OptionBoolean("screen.motion.effects", true));
+
+    public static final @NotNull OptionBoolean FULLSCREEN = register(new OptionBoolean("fullscreen", Minecraft.isClientASteamDeck())
+        .addOnChangeCallback((mc, option) -> mc.gameWindow.updateWindowState()));
+    public static final @NotNull OptionBoolean BORDERLESS_FULLSCREEN = register(new OptionBoolean("borderlessFullscreen", true)
+        .addOnChangeCallback((mc, option) -> {
+            if (FULLSCREEN.value) mc.gameWindow.updateWindowState();
+        }));
+    public static final @NotNull OptionBoolean START_IN_FULLSCREEN = register(new OptionBoolean("startInFullscreen", true));
+    public static final @NotNull OptionTooltip TOOLTIP_STYLE = register(new OptionTooltip("tooltipStyle", "default")
+        .withDisplayStringProvider((mc, i18n, option) -> {
+            TooltipElement.Style style = TooltipElement.styleMap.get(option.value);
+            if (style != null) {
+                return i18n.translateKey(style.translationKey);
+            }
+            return "Unknown";
+        }));
+    public static final @NotNull OptionFont FONT = register(new OptionFont("font", Fonts.DEFAULT)
+        .withDisplayStringProvider((mc, i18n, option) -> i18n.translateKey("options.font." + option.value.getKey())));
+    public static final @NotNull OptionEnum<LightmapStyle> LIGHTMAP_STYLE = register(new OptionEnum<>("lightmapStyle", LightmapStyle.class, LightmapStyle.GRAY)
+        .withDisplayStringProvider((mc, i18n, option) -> i18n.translateKey(option.value.getTranslationKey())));
+    public static final @NotNull OptionBoolean CUSTOM_LIGHTMAP = register(new OptionBoolean("customLightmap", true)
+        .addOnChangeCallback((mc, option) -> mc.worldRenderer.lightmapHelper.setup()));
+    public static final @NotNull OptionBoolean FOG = register(new OptionBoolean("fog", true));
+    public static final @NotNull OptionBoolean HIDE_UNDISCOVERED_ITEMS = register(new OptionBoolean("hideUndiscoveredItems", true));
+    public static final @NotNull OptionBoolean MUTE_ON_LOST_FOCUS = register(new OptionBoolean("muteOnLostFocus", false));
+    public static final @NotNull OptionBoolean AURORA = register(new OptionBoolean("aurora", true));
+    public static final @NotNull OptionBoolean MOB_VARIANTS = register(new OptionBoolean("mobVariants", true));
+    public static final @NotNull OptionEnum<Colorblindness> COLORBLINDNESS_FIX = register(new OptionEnum<>("colorblindnessFix", Colorblindness.class, Colorblindness.NONE));
+    public static final @NotNull OptionBoolean SUBTITLES = register(new OptionBoolean("subtitles", false));
+    public static final @NotNull OptionBoolean DEVELOPER_MODE = register(new OptionBoolean("developerMode", false));
+    public static final @NotNull OptionBoolean VIEW_SUPPORT_MODE = register(new OptionBoolean("viewSupportMode", false));
+    public static final @NotNull OptionBoolean ENABLE_HOLIDAY_TEXTURES = register(new OptionBoolean("enableHolidayTextures", true)
+        .addOnChangeCallback((mc, option) -> {
+            mc.textureManager.refreshTexturesAndDisplayErrors();
+            mc.renderGlobal.allChanged();
+        }));
+    public static final @NotNull OptionBoolean DYNAMIC_CURSOR = register(new OptionBoolean("dynamicCursor", true));
+    public static final @NotNull OptionBoolean DEV_MODELS = register(new OptionBoolean("devModels", true));
+    public static final @NotNull OptionBoolean DO_JCE_CHECK = register(new OptionBoolean("doJCECheck", true));
+    public static final @NotNull OptionString UUID_SERVER = register(new OptionString("uuidServer", "https://api.minecraftservices.com/minecraft/profile/lookup/name/%s"));
+
+    public static final @NotNull OptionBoolean PLAYER_LEFT_HANDED = register(new OptionBoolean("player.left.handed", false)
+        .addOnChangeCallback((mc, option) -> {
+            if (mc.thePlayer != null) {
+                mc.thePlayer.playerConfig.setLeftHand(option.value);
+            }
+        }));
+    public static final @NotNull OptionBoolean PLAYER_CAPE = register(new OptionBoolean("player.cape", true)
+        .addOnChangeCallback((mc, option) -> {
+            if (mc.thePlayer != null) {
+                mc.thePlayer.playerConfig.setCape(option.value);
+            }
+        }));
+    public static final @NotNull OptionBoolean PLAYER_HAT = register(new OptionBoolean("player.hat", true)
+        .addOnChangeCallback((mc, option) -> {
+            if (mc.thePlayer != null) {
+                mc.thePlayer.playerConfig.setHat(option.value);
+            }
+        }));
+    public static final @NotNull OptionBoolean PLAYER_JACKET = register(new OptionBoolean("player.jacket", true)
+        .addOnChangeCallback((mc, option) -> {
+            if (mc.thePlayer != null) {
+                mc.thePlayer.playerConfig.setJacket(option.value);
+            }
+        }));
+    public static final @NotNull OptionBoolean PLAYER_SLEEVE_LEFT = register(new OptionBoolean("player.sleeve.left", true)
+        .addOnChangeCallback((mc, option) -> {
+            if (mc.thePlayer != null) {
+                mc.thePlayer.playerConfig.setSleeveLeft(option.value);
+            }
+        }));
+    public static final @NotNull OptionBoolean PLAYER_SLEEVE_RIGHT = register(new OptionBoolean("player.sleeve.right", true)
+        .addOnChangeCallback((mc, option) -> {
+            if (mc.thePlayer != null) {
+                mc.thePlayer.playerConfig.setSleeveRight(option.value);
+            }
+        }));
+    public static final @NotNull OptionBoolean PLAYER_PANT_LEFT = register(new OptionBoolean("player.pant.left", true)
+        .addOnChangeCallback((mc, option) -> {
+            if (mc.thePlayer != null) {
+                mc.thePlayer.playerConfig.setPantLeft(option.value);
+            }
+        }));
+    public static final @NotNull OptionBoolean PLAYER_PANT_RIGHT = register(new OptionBoolean("player.pant.right", true)
+        .addOnChangeCallback((mc, option) -> {
+            if (mc.thePlayer != null) {
+                mc.thePlayer.playerConfig.setPantRight(option.value);
+            }
+        }));
+    public static final @NotNull OptionBoolean PLAYER_DEV_MODEL = register(new OptionBoolean("player.devmodel", true)
+        .addOnChangeCallback((mc, option) -> {
+            if (mc.thePlayer != null) {
+                mc.thePlayer.playerConfig.setDevModelEnabled(option.value);
+            }
+        }));
+    public static final @NotNull OptionEnum<Player.PlayerConfig.HurtSound> PLAYER_HURT_SOUND = register(new OptionEnum<>("player.hurtsound", Player.PlayerConfig.HurtSound.class, Player.PlayerConfig.HurtSound.MASCULINE)
+        .addOnChangeCallback((mc, option) -> {
+            if (mc.thePlayer != null) {
+                mc.thePlayer.playerConfig.setHurtSound(option.value);
+            }
+        }));
+
+    public static final @NotNull KeyBinding KEY_ATTACK = register(new KeyBinding("key.attack").setDefault(InputDevice.mouse, 0));
+    public static final @NotNull KeyBinding KEY_INTERACT = register(new KeyBinding("key.interact").setDefault(InputDevice.mouse, 1));
+    public static final @NotNull KeyBinding KEY_PICK_BLOCK = register(new KeyBinding("key.pickBlock").setDefault(InputDevice.mouse, 2));
+    public static final @NotNull KeyBinding KEY_SORT_INVENTORY = register(new KeyBinding("key.sortInventory").setDefault(InputDevice.mouse, 2));
+    public static final @NotNull KeyBinding KEY_FORWARD = register(new KeyBinding("key.forward").setDefault(InputDevice.keyboard, KEY_W));
+    public static final @NotNull KeyBinding KEY_LEFT = register(new KeyBinding("key.left").setDefault(InputDevice.keyboard, KEY_A));
+    public static final @NotNull KeyBinding KEY_BACK = register(new KeyBinding("key.back").setDefault(InputDevice.keyboard, KEY_S));
+    public static final @NotNull KeyBinding KEY_RIGHT = register(new KeyBinding("key.right").setDefault(InputDevice.keyboard, KEY_D));
+    public static final @NotNull KeyBinding KEY_JUMP = register(new KeyBinding("key.jump").setDefault(InputDevice.keyboard, KEY_SPACE));
+    public static final @NotNull KeyBinding KEY_INVENTORY = register(new KeyBinding("key.inventory").setDefault(InputDevice.keyboard, KEY_E));
+    public static final @NotNull KeyBinding KEY_DROP = register(new KeyBinding("key.drop").setDefault(InputDevice.keyboard, KEY_Q));
+    public static final @NotNull KeyBinding KEY_CHAT = register(new KeyBinding("key.chat").setDefault(InputDevice.keyboard, KEY_T));
+    public static final @NotNull KeyBinding KEY_COMMAND = register(new KeyBinding("key.command").setDefault(InputDevice.keyboard, KEY_SLASH));
+    public static final @NotNull KeyBinding KEY_TOGGLE_FOG = register(new KeyBinding("key.fog"));
+    public static final @NotNull KeyBinding KEY_TOGGLE_GAMMA = register(new KeyBinding("key.gamma"));
+    public static final @NotNull KeyBinding KEY_SNEAK = register(new KeyBinding("key.sneak").setDefault(InputDevice.keyboard, KEY_LSHIFT));
+    public static final @NotNull KeyBinding KEY_FLY = register(new KeyBinding("key.fly").setDefault(InputDevice.keyboard, KEY_LCONTROL));
+    public static final @NotNull KeyBinding KEY_GUIDEBOOK = register(new KeyBinding("key.guidebook").setDefault(InputDevice.keyboard, KEY_R));
+    public static final @NotNull KeyBinding KEY_DESCRIPTION = register(new KeyBinding("key.description").setDefault(InputDevice.keyboard, KEY_LCONTROL));
+    public static final @NotNull KeyBinding KEY_SHOW_RECIPE = register(new KeyBinding("key.showRecipe").setDefault(InputDevice.keyboard, KEY_R));
+    public static final @NotNull KeyBinding KEY_SHOW_USAGE = register(new KeyBinding("key.showUsage").setDefault(InputDevice.keyboard, KEY_U));
+    public static final @NotNull KeyBinding KEY_HOT_BAR_LEFT = register(new KeyBinding("key.hotbar.left").setDefault(InputDevice.keyboard, KEY_COMMA));
+    public static final @NotNull KeyBinding KEY_HOT_BAR_RIGHT = register(new KeyBinding("key.hotbar.right").setDefault(InputDevice.keyboard, KEY_PERIOD));
+    public static final @NotNull KeyBinding KEY_HOT_BAR_SWITCH = register(new KeyBinding("key.hotbar.switch").setDefault(InputDevice.keyboard, KEY_TAB));
+
+    public static final @NotNull KeyBinding KEY_HIDE_GUI = register(new KeyBinding("key.immersiveMode").setDefault(InputDevice.keyboard, KEY_F1));
+    public static final @NotNull KeyBinding KEY_SCREENSHOT = register(new KeyBinding("key.screenshot").setDefault(InputDevice.keyboard, KEY_F2));
+    public static final @NotNull KeyBinding KEY_TOGGLE_DEBUG = register(new KeyBinding("key.toggleDebug").setDefault(InputDevice.keyboard, KEY_F3));
+    public static final @NotNull KeyBinding KEY_TOGGLE_OVERLAY = register(new KeyBinding("key.toggleOverlay").setDefault(InputDevice.keyboard, KEY_F4));
+    public static final @NotNull KeyBinding KEY_SWITCH_PERSPECTIVE = register(new KeyBinding("key.switchPerspective").setDefault(InputDevice.keyboard, KEY_F5));
+    public static final @NotNull KeyBinding KEY_CINEMATIC_CAMERA = register(new KeyBinding("key.cinematicCamera").setDefault(InputDevice.keyboard, KEY_F8));
+    public static final @NotNull KeyBinding KEY_FULL_SCREEN = register(new KeyBinding("key.fullscreen").setDefault(InputDevice.keyboard, KEY_F11));
+    public static final @NotNull KeyBinding KEY_RELEASE_CURSOR = register(new KeyBinding("key.debug.releasecursor").setDefault(InputDevice.keyboard, KEY_F12));
+
+    public static final @NotNull KeyBinding KEY_HOT_BAR_SLOT_1 = register(new KeyBinding("key.hotbar.1").setDefault(InputDevice.keyboard, KEY_1));
+    public static final @NotNull KeyBinding KEY_HOT_BAR_SLOT_2 = register(new KeyBinding("key.hotbar.2").setDefault(InputDevice.keyboard, KEY_2));
+    public static final @NotNull KeyBinding KEY_HOT_BAR_SLOT_3 = register(new KeyBinding("key.hotbar.3").setDefault(InputDevice.keyboard, KEY_3));
+    public static final @NotNull KeyBinding KEY_HOT_BAR_SLOT_4 = register(new KeyBinding("key.hotbar.4").setDefault(InputDevice.keyboard, KEY_4));
+    public static final @NotNull KeyBinding KEY_HOT_BAR_SLOT_5 = register(new KeyBinding("key.hotbar.5").setDefault(InputDevice.keyboard, KEY_5));
+    public static final @NotNull KeyBinding KEY_HOT_BAR_SLOT_6 = register(new KeyBinding("key.hotbar.6").setDefault(InputDevice.keyboard, KEY_6));
+    public static final @NotNull KeyBinding KEY_HOT_BAR_SLOT_7 = register(new KeyBinding("key.hotbar.7").setDefault(InputDevice.keyboard, KEY_7));
+    public static final @NotNull KeyBinding KEY_HOT_BAR_SLOT_8 = register(new KeyBinding("key.hotbar.8").setDefault(InputDevice.keyboard, KEY_8));
+    public static final @NotNull KeyBinding KEY_HOT_BAR_SLOT_9 = register(new KeyBinding("key.hotbar.9").setDefault(InputDevice.keyboard, KEY_9));
+
+    public static final @NotNull KeyBinding KEY_LOOK_LEFT = register(new KeyBinding("key.look.left").setDefault(InputDevice.keyboard, Keyboard.KEY_LEFT));
+    public static final @NotNull KeyBinding KEY_LOOK_RIGHT = register(new KeyBinding("key.look.right").setDefault(InputDevice.keyboard, Keyboard.KEY_RIGHT));
+    public static final @NotNull KeyBinding KEY_LOOK_UP = register(new KeyBinding("key.look.up").setDefault(InputDevice.keyboard, KEY_UP));
+    public static final @NotNull KeyBinding KEY_LOOK_DOWN = register(new KeyBinding("key.look.down").setDefault(InputDevice.keyboard, KEY_DOWN));
+    public static final @NotNull KeyBinding KEY_CENTER_VIEW = register(new KeyBinding("key.look.center").setDefault(InputDevice.keyboard, KEY_END));
+    public static final @NotNull KeyBinding KEY_ZOOM = register(new KeyBinding("key.zoom").setDefault(InputDevice.keyboard, KEY_C));
+    public static final @NotNull KeyBinding KEY_PLAYER_LIST = register(new KeyBinding("key.playerList").setDefault(InputDevice.keyboard, KEY_L));
+    public static final @NotNull KeyBinding KEY_PHOTO_MODE = register(new KeyBinding("key.photoMode").setDefault(InputDevice.keyboard, KEY_P));
+    public static final @NotNull KeyBinding KEY_LOCK_ROTATION = register(new KeyBinding("key.lockRotation").setDefault(InputDevice.keyboard, KEY_Z));
+    public static final @NotNull KeyBinding KEY_AUTO_WALK = register(new KeyBinding("key.autoWalk"));
+    public static final @NotNull KeyBinding KEY_EASY_BRIDGE = register(new KeyBinding("key.easyBridge"));
+    public static final @NotNull KeyBinding KEY_SPRINT = register(new KeyBinding("key.sprint"));
+    public static final @NotNull KeyBinding KEY_OPEN_ACHIEVEMENTS = register(new KeyBinding("key.openAchievements"));
+    public static final @NotNull KeyBinding KEY_OPEN_STATISTICS = register(new KeyBinding("key.openStatistics"));
+    public static final @NotNull KeyBinding KEY_SHOW_CONSOLE = register(new KeyBinding("key.showConsole").setDefault(InputDevice.keyboard, KEY_GRAVE));
+
+    public static final @NotNull List<KeyBinding> DEBUG_KEYS = new ArrayList<>();
+    public static final @NotNull KeyBinding KEY_RELOAD = register(new KeyBinding("key.debug.reload").setDefault(InputDevice.keyboard, KEY_R));
+    public static final @NotNull KeyBinding KEY_SWITCH_GAMEMODE = register(new KeyBinding("key.debug.gamemode").setDefault(InputDevice.keyboard, KEY_N));
+    public static final @NotNull KeyBinding KEY_DUMP_TEXTURES = register(new KeyBinding("key.debug.dumptextures").setDefault(InputDevice.keyboard, KEY_D));
+    public static final @NotNull KeyBinding KEY_FULLBRIGHT = register(new KeyBinding("key.debug.fullbright").setDefault(InputDevice.keyboard, KEY_F));
+    public static final @NotNull KeyBinding KEY_LIGHTMAPS = register(new KeyBinding("key.debug.lightmap").setDefault(InputDevice.keyboard, KEY_L));
+    public static final @NotNull KeyBinding KEY_COLLISION_BOXES = register(new KeyBinding("key.debug.collision").setDefault(InputDevice.keyboard, KEY_B));
+    public static final @NotNull KeyBinding KEY_CHUNK_BORDERS = register(new KeyBinding("key.debug.chunkborders").setDefault(InputDevice.keyboard, KEY_G));
+    public static final @NotNull KeyBinding KEY_CLEAR_CHAT = register(new KeyBinding("key.debug.clearchat").setDefault(InputDevice.keyboard, KEY_C));
+    public static final @NotNull KeyBinding KEY_PAUSE_LOST_FOCUS = register(new KeyBinding("key.debug.pauseFocus").setDefault(InputDevice.keyboard, KEY_P));
+    public static final @NotNull KeyBinding KEY_TOGGLE_ITEM_INFO = register(new KeyBinding("key.debug.iteminfo").setDefault(InputDevice.keyboard, KEY_H));
+    public static final @NotNull KeyBinding KEY_RELOAD_CHUNKS = register(new KeyBinding("key.debug.reloadchunks").setDefault(InputDevice.keyboard, KEY_A));
+    public static final @NotNull KeyBinding KEY_SMOOTH_LIGHTING = register(new KeyBinding("key.debug.smoothlighting").setDefault(InputDevice.keyboard, KEY_S));
+    public static final @NotNull KeyBinding KEY_SHOW_SHORTCUTS = register(new KeyBinding("key.debug.shortcuts").setDefault(InputDevice.keyboard, KEY_Q));
+    public static final @NotNull KeyBinding KEY_TOGGLE_TEXTURE_ATLAS = register(new KeyBinding("key.debug.textureAtlas"));
+    public static final @NotNull KeyBinding KEY_LOAD_CHUNKS_QUICKLY = register(new KeyBinding("key.debug.loadChunksQuickly"));
+
+    static {
+        DEBUG_KEYS.add(KEY_SHOW_SHORTCUTS);
+        DEBUG_KEYS.add(KEY_RELOAD);
+        DEBUG_KEYS.add(KEY_SWITCH_GAMEMODE);
+        DEBUG_KEYS.add(KEY_DUMP_TEXTURES);
+        DEBUG_KEYS.add(KEY_FULLBRIGHT);
+        DEBUG_KEYS.add(KEY_LIGHTMAPS);
+        DEBUG_KEYS.add(KEY_COLLISION_BOXES);
+        DEBUG_KEYS.add(KEY_CHUNK_BORDERS);
+        DEBUG_KEYS.add(KEY_CLEAR_CHAT);
+        DEBUG_KEYS.add(KEY_PAUSE_LOST_FOCUS);
+        DEBUG_KEYS.add(KEY_TOGGLE_ITEM_INFO);
+        DEBUG_KEYS.add(KEY_RELOAD_CHUNKS);
+        DEBUG_KEYS.add(KEY_SMOOTH_LIGHTING);
+    }
+
+    private static File optionsFile;
+
+    public static @NotNull <T extends Option<E>, E> T register(@NotNull T option) {
+        if (registeredOptions.containsKey(option.id))
+            throw new IllegalArgumentException("Option with name '" + option.id + "' is already registered!");
+        registeredOptions.put(option.id, option);
+        allOptions.add(option);
+        if (savedValues.containsKey(option.id)) {
+            option.fromOptionsString(savedValues.get(option.id));
+        }
+        return option;
+    }
+
+    public static @NotNull KeyBinding register(@NotNull KeyBinding keyBinding) {
+        if (registeredKeys.containsKey(keyBinding.getId()))
+            throw new IllegalArgumentException("Keybinding with name '" + keyBinding.getId() + "' is already registered!");
+        registeredKeys.put(keyBinding.getId(), keyBinding);
+        allKeys.add(keyBinding);
+        if (savedValues.containsKey("key_" + keyBinding.getId())) {
+            keyBinding.fromOptionsString(savedValues.get("key_" + keyBinding.getId()));
+        }
+        return keyBinding;
+    }
+
+    public static void init(@NotNull File mcDirectory) {
+        GameSettings.optionsFile = new File(mcDirectory, "options.txt");
+        HudComponents.DEFAULT_LAYOUT = HudComponents.INSTANCE.toSettingsString();
+
+        loadOptions();
+        saveOptions();
+    }
+
+    public static void loadOptions() {
+        if (optionsFile == null || !optionsFile.exists()) return;
+        try {
+            BufferedReader br = new BufferedReader(new FileReader(optionsFile));
+            br.lines().forEach(line -> {
+                    int i = line.indexOf(':');
+                    String key = line.substring(0, i);
+                    String value = line.substring(i + 1);
+                    savedValues.put(key, value);
+                }
+            );
+            br.close();
+        } catch (Exception e) {
+            LOGGER.error("Failed to load options", e);
+        }
+
+        try {
+            for (var entry : savedValues.entrySet()) {
+                String key = entry.getKey();
+                String value = entry.getValue();
+
+                if (key.equals("hudLayout")) {
+                    HudComponents.INSTANCE.fromSettingsString(value);
+                    continue;
+                }
+
+                Option<?> option = getOption(key);
+                if (option != null) {
+                    option.fromOptionsString(value);
+                    continue;
+                }
+
+                KeyBinding keyBinding = getKeyBinding(key.replaceFirst("key_", ""));
+                if (keyBinding != null) {
+                    keyBinding.fromOptionsString(value);
+                }
+            }
+        } catch (Exception e) {
+            LOGGER.error("Failed to load options", e);
+        }
+    }
+
+    public static void saveOptions() {
+        for (var option : allOptions) {
+            savedValues.put(option.id, option.toOptionsString());
+        }
+        for (var keyBind : allKeys) {
+            savedValues.put("key_" + keyBind.getId(), keyBind.toOptionsString());
+        }
+        savedValues.put("hudLayout", HudComponents.INSTANCE.toSettingsString());
+        try {
+            PrintWriter printwriter = new PrintWriter(new FileWriter(optionsFile));
+
+            List<String> keys = new ArrayList<>(savedValues.keySet());
+            keys.sort(String::compareTo);
+            for (var key : keys) {
+                printwriter.print(key);
+                printwriter.print(":");
+                printwriter.println(savedValues.get(key));
+            }
+
+            printwriter.close();
+        } catch (Exception exception) {
+            LOGGER.error("Failed to save options", exception);
+        }
+    }
 
 }
diff --git a/game/client/src/main/java/net/minecraft/client/option/KeyBinding.java b/game/client/src/main/java/net/minecraft/client/option/KeyBinding.java
index 62ed5f654..dc381a2c7 100644
--- a/game/client/src/main/java/net/minecraft/client/option/KeyBinding.java
+++ b/game/client/src/main/java/net/minecraft/client/option/KeyBinding.java
@@ -9,8 +9,8 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 public class KeyBinding {
-	private static Map<Character, InputDevice> charToInputDeviceMap = new HashMap<>();
-	private static Map<InputDevice, Character> inputDeviceToCharMap = new HashMap<>();
+	private static final Map<Character, InputDevice> charToInputDeviceMap = new HashMap<>();
+	private static final Map<InputDevice, Character> inputDeviceToCharMap = new HashMap<>();
 	
 	public static void addInputDevice(char c, InputDevice inputDevice) {
 		if(charToInputDeviceMap.containsKey(c)) {
@@ -28,7 +28,7 @@ public class KeyBinding {
 		addInputDevice('k', InputDevice.keyboard);
 	}
 	
-	private final String id;
+	private final @NotNull String id;
 	
 	private @Nullable InputDevice inputDevice;
 	private int keyCode = -1;
@@ -36,11 +36,10 @@ public class KeyBinding {
 	private @Nullable InputDevice defaultInputDevice = null;
 	private int defaultKeyCode = -1;
 
-	public KeyBinding(String id) {
+	public KeyBinding(@NotNull String id) {
 		this.id = id;
 		this.inputDevice = null;
 		this.keyCode = -1;
-		GameSettings.keys.add(this);
 	}
 
 	public @NotNull KeyBinding setDefault(final @Nullable InputDevice device, final int keyCode) {
@@ -71,8 +70,8 @@ public class KeyBinding {
 	}
 
 	public @NotNull KeyBinding resetToDefault() {
-		this.keyCode = defaultKeyCode;
-		this.inputDevice = defaultInputDevice;
+		this.keyCode = this.defaultKeyCode;
+		this.inputDevice = this.defaultInputDevice;
 		return this;
 	}
 
@@ -81,60 +80,60 @@ public class KeyBinding {
 	}
 
 	public String getId() {
-		return id;
+		return this.id;
 	}
 
 	public InputDevice getInputDevice() {
-		return inputDevice;
+		return this.inputDevice;
 	}
 	
 	public int getKeyCode() {
-		return keyCode;
+		return this.keyCode;
 	}
 
 	public InputDevice getDefaultInputDevice() {
-		return defaultInputDevice;
+		return this.defaultInputDevice;
 	}
 
 	public int getDefaultKeyCode() {
-		return defaultKeyCode;
+		return this.defaultKeyCode;
 	}
 
 	public boolean isPressed() {
-		if(inputDevice != null) {
-			return inputDevice.isPressed(keyCode);
+		if(this.inputDevice != null) {
+			return this.inputDevice.isPressed(this.keyCode);
 		}
 		return false;
 	}
 
 	public boolean isPressEvent(InputDevice eventInputDevice) {
-		if(inputDevice == eventInputDevice) {
-			return inputDevice.isPressEvent(keyCode);
+		if(this.inputDevice == eventInputDevice) {
+			return this.inputDevice.isPressEvent(this.keyCode);
 		}
 		return false;
 	}
 	public boolean isPressEvent() {
-		if(inputDevice != null) {
-			return inputDevice.isPressEvent(keyCode);
+		if(this.inputDevice != null) {
+			return this.inputDevice.isPressEvent(this.keyCode);
 		}
 		return false;
 	}
 
 	public boolean isReleaseEvent(InputDevice eventInputDevice) {
-		if(inputDevice == eventInputDevice) {
-			return inputDevice.isReleaseEvent(keyCode);
+		if(this.inputDevice == eventInputDevice) {
+			return this.inputDevice.isReleaseEvent(this.keyCode);
 		}
 		return false;
 	}
 	public boolean isReleaseEvent() {
-		if(inputDevice != null) {
-			return inputDevice.isReleaseEvent(keyCode);
+		if(this.inputDevice != null) {
+			return this.inputDevice.isReleaseEvent(this.keyCode);
 		}
 		return false;
 	}
 
 	public void fromOptionsString(String value) {
-		if(value.length() == 0) {
+		if(value.isEmpty()) {
 			unbind();
 			return;
 		}
@@ -160,23 +159,23 @@ public class KeyBinding {
 	}
 
 	public String toOptionsString() {
-		Character c = inputDeviceToCharMap.get(inputDevice);
+		Character c = inputDeviceToCharMap.get(this.inputDevice);
 		if(c != null) {
-			return String.valueOf(c) + keyCode;
+			return String.valueOf(c) + this.keyCode;
 		}
 		return "";
 	}
 	
 	public boolean isKeyboardKey(int key) {
-		if(inputDevice == InputDevice.keyboard) {
-			return keyCode == key;
+		if(this.inputDevice == InputDevice.keyboard) {
+			return this.keyCode == key;
 		}
 		return false;
 	}
 
 	public boolean isMouseButton(int button) {
-		if(inputDevice == InputDevice.mouse) {
-			return keyCode == button;
+		if(this.inputDevice == InputDevice.mouse) {
+			return this.keyCode == button;
 		}
 		return false;
 	}
@@ -186,17 +185,17 @@ public class KeyBinding {
 	}
 	
 	public boolean isBound() {
-		return inputDevice != null;
+		return this.inputDevice != null;
 	}
 	
 	public String getKeyName() {
-		if(inputDevice == null) {
+		if(this.inputDevice == null) {
 			return I18n.getInstance().translateKey("key.disabled");
 		}
 		
-		String keyName = inputDevice.getKeyName(keyCode);
+		String keyName = this.inputDevice.getKeyName(this.keyCode);
 		if(keyName == null) {
-			keyName = String.valueOf(keyCode);
+			keyName = String.valueOf(this.keyCode);
 		} else if ("LCONTROL".equals(keyName)) {
 			keyName = "LCTRL";
 		} else if ("RCONTROL".equals(keyName)) {
diff --git a/game/client/src/main/java/net/minecraft/client/option/Option.java b/game/client/src/main/java/net/minecraft/client/option/Option.java
index c76c55881..bcedbf30a 100644
--- a/game/client/src/main/java/net/minecraft/client/option/Option.java
+++ b/game/client/src/main/java/net/minecraft/client/option/Option.java
@@ -1,8 +1,9 @@
 package net.minecraft.client.option;
 
-import net.minecraft.client.gui.paged.CallbackComponent;
+import net.minecraft.client.Minecraft;
 import net.minecraft.core.lang.I18n;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -10,54 +11,59 @@ import java.util.List;
 import static net.minecraft.core.util.Util.emptyStringIfNull;
 
 public abstract class Option<E> {
-
-	public final @NotNull GameSettings gameSettings;
-	public final @NotNull String name;
+	public final @NotNull String id;
 	public @NotNull E value;
 	protected final @NotNull E defaultValue;
-	protected final List<OptionCallback<E>> callbacks = new ArrayList<>();
+	protected @Nullable DisplayStringProvider<E> displayStringProvider;
+	protected final List<OptionCallback<E>> onChangeCallbacks = new ArrayList<>();
 
-	public Option(final @NotNull GameSettings gameSettings, final @NotNull String name, final @NotNull E defaultValue) {
-		this.gameSettings = gameSettings;
-		this.name = name;
+	public Option(final @NotNull String id, final @NotNull E defaultValue) {
+		this.id = id;
 		this.value = defaultValue;
 		this.defaultValue = defaultValue;
-		GameSettings.options.add(this);
 	}
 
 	public void set(final @NotNull E value) {
 		this.value = value;
 	}
 
-	public void addCallback(final @NotNull OptionCallback<E> callback) {
-		this.callbacks.add(callback);
+	public <T extends Option<E>> @NotNull T addOnChangeCallback(final @NotNull OptionCallback<E> callback) {
+		this.onChangeCallbacks.add(callback);
+		return (T) this;
+	}
+
+	public <T extends Option<E>> @NotNull T withDisplayStringProvider(final @NotNull DisplayStringProvider<E> provider) {
+		this.displayStringProvider = provider;
+		return (T) this;
 	}
 
-	public abstract void parse(final @NotNull String string);
+	public abstract void fromOptionsString(final @NotNull String string);
 
 	public void onUpdate() {
-		for (final @NotNull OptionCallback<E> callback : this.callbacks) {
-			callback.onUpdate(this);
+		for (final @NotNull OptionCallback<E> callback : this.onChangeCallbacks) {
+			callback.onUpdate(Minecraft.getMinecraft(), this);
 		}
-        this.gameSettings.optionChanged(this);
     }
 
 	public @NotNull String getDisplayString() {
-        return this.gameSettings.getDisplayString(this);
+		if (this.displayStringProvider != null) {
+			return this.displayStringProvider.getDisplayString(Minecraft.getMinecraft(), I18n.getInstance(), this);
+		}
+		return toOptionsString();
     }
 
 	public @NotNull String getDisplayStringValue() {
-        return this.gameSettings.getDisplayString(this);
+        return getDisplayString();
     }
 
 	public @NotNull String getDisplayStringName() {
-		return I18n.getInstance().translateKey("options." + this.name);
+		return I18n.getInstance().translateKey("options." + this.id);
 	}
 
 	/**
 	 * The String that is saved to the options.txt file. Don't include spaces!
 	 */
-	public @NotNull String getValueString() {
+	public @NotNull String toOptionsString() {
 		return emptyStringIfNull(this.value.toString());
 	}
 
@@ -66,6 +72,10 @@ public abstract class Option<E> {
 	}
 
 	public interface OptionCallback<T> {
-		void onUpdate(Option<T> option);
+		void onUpdate(@NotNull Minecraft mc, @NotNull Option<T> option);
+	}
+
+	public interface DisplayStringProvider<T> {
+		@NotNull String getDisplayString(@NotNull Minecraft mc, @NotNull I18n i18n, @NotNull Option<T> option);
 	}
 }
diff --git a/game/client/src/main/java/net/minecraft/client/option/OptionBoolean.java b/game/client/src/main/java/net/minecraft/client/option/OptionBoolean.java
index 876d9dce4..851162df1 100644
--- a/game/client/src/main/java/net/minecraft/client/option/OptionBoolean.java
+++ b/game/client/src/main/java/net/minecraft/client/option/OptionBoolean.java
@@ -1,14 +1,16 @@
 package net.minecraft.client.option;
 
+import net.minecraft.client.Minecraft;
+import net.minecraft.core.lang.I18n;
 import net.minecraft.core.util.helper.Toggleable;
 import org.jetbrains.annotations.NotNull;
 
-public class OptionBoolean extends OptionToggleable<Boolean> implements Toggleable{
+public class OptionBoolean extends OptionToggleable<@NotNull Boolean> implements Toggleable{
 	
 	public static final Boolean[] values = new Boolean[] {false, true};
 	
-	public OptionBoolean(GameSettings gameSettings, String name, boolean value) {
-		super(gameSettings, name, value, values);
+	public OptionBoolean(@NotNull String name, boolean value) {
+		super(name, value, values);
 	}
 	
 	public boolean isBoolean() {
@@ -16,7 +18,7 @@ public class OptionBoolean extends OptionToggleable<Boolean> implements Toggleab
 	}
 
 	@Override
-	public void parse(@NotNull String string) {
+	public void fromOptionsString(@NotNull String string) {
 		this.value = string.equalsIgnoreCase("true");
 	}
 
@@ -26,7 +28,19 @@ public class OptionBoolean extends OptionToggleable<Boolean> implements Toggleab
 	}
 
 	public boolean isTrue() {
-		return this.value != null && this.value;
+		return this.value;
+	}
+
+	@Override
+	public @NotNull String getDisplayString() {
+		I18n i18n = I18n.getInstance();
+		if (this.displayStringProvider != null) {
+			return this.displayStringProvider.getDisplayString(Minecraft.getMinecraft(), i18n, this);
+		}
+		if (this.value) {
+			return i18n.translateKey("options.on");
+		} else {
+			return i18n.translateKey("options.off");
+		}
 	}
-	
 }
diff --git a/game/client/src/main/java/net/minecraft/client/option/OptionColor.java b/game/client/src/main/java/net/minecraft/client/option/OptionColor.java
index cecc457db..394c34b04 100644
--- a/game/client/src/main/java/net/minecraft/client/option/OptionColor.java
+++ b/game/client/src/main/java/net/minecraft/client/option/OptionColor.java
@@ -7,12 +7,12 @@ import org.slf4j.Logger;
 
 public class OptionColor extends Option<Color>{
 	private static final Logger LOGGER = LogUtils.getLogger();
-	public OptionColor(GameSettings gameSettings, String name, Color defaultValue) {
-		super(gameSettings, name, defaultValue);
+	public OptionColor(@NotNull String name, @NotNull Color defaultValue) {
+		super(name, defaultValue);
 	}
 
 	@Override
-	public void parse(@NotNull String string) {
+	public void fromOptionsString(@NotNull String string) {
 		try{
 			this.value.parse(string);
 		}catch (Exception e) {
@@ -21,8 +21,8 @@ public class OptionColor extends Option<Color>{
 	}
 	
 	@Override
-	public @NotNull String getValueString() {
-		return value.toPropertiesString();
+	public @NotNull String toOptionsString() {
+		return this.value.toPropertiesString();
 	}
 
 }
diff --git a/game/client/src/main/java/net/minecraft/client/option/OptionEnum.java b/game/client/src/main/java/net/minecraft/client/option/OptionEnum.java
index 3693e8c04..731c3943e 100644
--- a/game/client/src/main/java/net/minecraft/client/option/OptionEnum.java
+++ b/game/client/src/main/java/net/minecraft/client/option/OptionEnum.java
@@ -1,5 +1,8 @@
 package net.minecraft.client.option;
 
+import net.minecraft.client.Minecraft;
+import net.minecraft.core.lang.I18n;
+import net.minecraft.core.util.helper.ITranslatable;
 import net.minecraft.core.util.helper.Toggleable;
 import org.jetbrains.annotations.NotNull;
 
@@ -7,17 +10,17 @@ public class OptionEnum<E extends Enum<?>> extends OptionToggleable<E> implement
 	
 	private boolean isSlider;
 	
-	public OptionEnum(GameSettings gameSettings, String name, Class<E> clazz) {
-		this(gameSettings, name, clazz, clazz.getEnumConstants()[0]);
+	public OptionEnum(@NotNull String name, @NotNull Class<E> clazz) {
+		this(name, clazz, clazz.getEnumConstants()[0]);
 	}
 
-	public OptionEnum(GameSettings gameSettings, String name, Class<E> clazz, E defaultValue) {
-		super(gameSettings, name, defaultValue, clazz.getEnumConstants());
+	public OptionEnum(@NotNull String name, @NotNull Class<E> clazz, @NotNull E defaultValue) {
+		super(name, defaultValue, clazz.getEnumConstants());
 	}
 
 	@Override
-	public void parse(@NotNull String string) {
-		for(E e : values) {
+	public void fromOptionsString(@NotNull String string) {
+		for(E e : this.values) {
 			if(e.toString().equalsIgnoreCase(string)) {
 				this.value = e;
 			}
@@ -31,7 +34,21 @@ public class OptionEnum<E extends Enum<?>> extends OptionToggleable<E> implement
 	
 	@Override
 	public boolean isSlider() {
-		return isSlider;
+		return this.isSlider;
 	}
 
+	@Override
+	public @NotNull String getDisplayString() {
+		I18n i18n = I18n.getInstance();
+		if (this.displayStringProvider != null) {
+			return this.displayStringProvider.getDisplayString(Minecraft.getMinecraft(), i18n, this);
+		}
+		String key;
+		if (this.value instanceof ITranslatable translatable) {
+			key = translatable.getTranslationKey();
+		} else {
+			key = this.value.toString().toLowerCase();
+		}
+		return i18n.translateKey("options." + this.id + "." + key);
+	}
 }
diff --git a/game/client/src/main/java/net/minecraft/client/option/OptionFloat.java b/game/client/src/main/java/net/minecraft/client/option/OptionFloat.java
index 20b5cde37..e02d31ebc 100644
--- a/game/client/src/main/java/net/minecraft/client/option/OptionFloat.java
+++ b/game/client/src/main/java/net/minecraft/client/option/OptionFloat.java
@@ -1,11 +1,13 @@
 package net.minecraft.client.option;
 
+import net.minecraft.client.Minecraft;
+import net.minecraft.core.lang.I18n;
 import org.jetbrains.annotations.NotNull;
 
 public class OptionFloat extends Option<Float>{
 
-	public OptionFloat(GameSettings gameSettings, String name, float value) {
-		super(gameSettings, name, value);
+	public OptionFloat(@NotNull String name, float value) {
+		super(name, value);
 	}
 
 
@@ -18,7 +20,7 @@ public class OptionFloat extends Option<Float>{
 	}
 
 	@Override
-	public void parse(@NotNull String string) {
+	public void fromOptionsString(@NotNull String string) {
 		if(string.equalsIgnoreCase("true")) {
 			this.value = 1.0f;
 			return;
@@ -31,4 +33,16 @@ public class OptionFloat extends Option<Float>{
 		this.value = Float.parseFloat(string);
 	}
 
+	@Override
+	public @NotNull String getDisplayString() {
+		I18n i18n = I18n.getInstance();
+		if (this.displayStringProvider != null) {
+			return this.displayStringProvider.getDisplayString(Minecraft.getMinecraft(), I18n.getInstance(), this);
+		}
+		if (this.value == 0.0F) {
+			return i18n.translateKey("options.off");
+		} else {
+			return (int) (this.value * 100F) + "%";
+		}
+	}
 }
diff --git a/game/client/src/main/java/net/minecraft/client/option/OptionFont.java b/game/client/src/main/java/net/minecraft/client/option/OptionFont.java
index 6e4de8fdb..89fc679e5 100644
--- a/game/client/src/main/java/net/minecraft/client/option/OptionFont.java
+++ b/game/client/src/main/java/net/minecraft/client/option/OptionFont.java
@@ -8,12 +8,12 @@ import org.jetbrains.annotations.NotNull;
 
 public class OptionFont extends OptionToggleable<@NotNull Font> implements Toggleable {
 
-    public OptionFont(final GameSettings gameSettings, final String name, final @NotNull Font defaultValue) {
-        super(gameSettings, name, defaultValue, null);
+    public OptionFont(final @NotNull String name, final @NotNull Font defaultValue) {
+        super(name, defaultValue, null);
     }
 
     @Override
-    public void parse(final @NotNull String string) {
+    public void fromOptionsString(final @NotNull String string) {
         this.value = Fonts.fontWithKey(string);
     }
 
@@ -48,7 +48,7 @@ public class OptionFont extends OptionToggleable<@NotNull Font> implements Toggl
     }
 
     @Override
-    public @NotNull String getValueString() {
+    public @NotNull String toOptionsString() {
         return this.value.getKey();
     }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/option/OptionGuiScale.java b/game/client/src/main/java/net/minecraft/client/option/OptionGuiScale.java
new file mode 100644
index 000000000..b39001470
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/option/OptionGuiScale.java
@@ -0,0 +1,58 @@
+package net.minecraft.client.option;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.ScaledResolution;
+import org.jetbrains.annotations.NotNull;
+
+public class OptionGuiScale extends OptionToggleable<Integer> {
+    public OptionGuiScale(String name, Integer defaultValue) {
+        super(name, defaultValue, new Integer[1]);
+    }
+
+    @Override
+    public void toggle() {
+        toggle(1);
+    }
+
+    @Override
+    public void toggle(int delta) {
+        int size = size();
+        setValueWithIndex((getValueIndex() + delta) % size);
+    }
+
+    @Override
+    public int getValueIndex() {
+        if (this.value == 0) {
+            return 0;
+        } else {
+            return size() - this.value;
+        }
+    }
+
+    @Override
+    public void setValueWithIndex(int i) {
+        if (i != 0) {
+            this.value = size() - i;
+        } else {
+            this.value = i;
+        }
+    }
+
+    @Override
+    public int size() {
+        Minecraft mc = Minecraft.getMinecraft();
+        int width = mc.resolution.getWidthScreenCoords();
+        int height = mc.resolution.getHeightScreenCoords();
+        return ScaledResolution.getMaxScale(width, height);
+    }
+
+    @Override
+    public boolean isSlider() {
+        return true;
+    }
+
+    @Override
+    public void fromOptionsString(@NotNull String string) {
+        this.value = Integer.parseInt(string);
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/option/OptionImmersiveMode.java b/game/client/src/main/java/net/minecraft/client/option/OptionImmersiveMode.java
index 23034b3a9..77feec4dc 100644
--- a/game/client/src/main/java/net/minecraft/client/option/OptionImmersiveMode.java
+++ b/game/client/src/main/java/net/minecraft/client/option/OptionImmersiveMode.java
@@ -2,45 +2,45 @@ package net.minecraft.client.option;
 
 public class OptionImmersiveMode extends OptionInteger {
 
-	public OptionImmersiveMode(GameSettings gameSettings) {
-		super(gameSettings, "immersiveMode", 0);
+	public OptionImmersiveMode() {
+		super("immersiveMode", 0);
 	}
 	
 	public void toggle() {
-		value++;
-		value %= 3;
+        this.value++;
+        this.value %= 3;
 	}
 	
 	public boolean drawHand() {
-		return value < 2;
+		return this.value < 2;
 	}
 	
 	public boolean drawChat() {
-		return value < 2;
+		return this.value < 2;
 	}
 	
 	public boolean drawOutline() {
-		return value < 2;
+		return this.value < 2;
 	}
 	
 	public boolean drawNames() {
-		return value < 1;
+		return this.value < 1;
 	}
 	
 	public boolean drawHotbar() {
-		return value < 1;
+		return this.value < 1;
 	}
 	
 	public boolean drawOverlays() {
-		return value < 1;
+		return this.value < 1;
 	}
 	
 	public boolean drawCrosshair() {
-		return value < 2;
+		return this.value < 2;
 	}
 	
 	public boolean drawVignette() {
-		return value < 2;
+		return this.value < 2;
 	}
 	
 	
diff --git a/game/client/src/main/java/net/minecraft/client/option/OptionInteger.java b/game/client/src/main/java/net/minecraft/client/option/OptionInteger.java
index 254c6b368..0756e67d4 100644
--- a/game/client/src/main/java/net/minecraft/client/option/OptionInteger.java
+++ b/game/client/src/main/java/net/minecraft/client/option/OptionInteger.java
@@ -4,12 +4,12 @@ import org.jetbrains.annotations.NotNull;
 
 public class OptionInteger extends Option<Integer>{
 
-	public OptionInteger(GameSettings gameSettings, String name, int defaultValue) {
-		super(gameSettings, name, defaultValue);
+	public OptionInteger(@NotNull String name, int defaultValue) {
+		super(name, defaultValue);
 	}
 
 	@Override
-	public void parse(@NotNull String string) {
+	public void fromOptionsString(@NotNull String string) {
 		this.value = Integer.parseInt(string);
 	}
 
diff --git a/game/client/src/main/java/net/minecraft/client/option/OptionRange.java b/game/client/src/main/java/net/minecraft/client/option/OptionRange.java
index e4f3a3299..36a7d9096 100644
--- a/game/client/src/main/java/net/minecraft/client/option/OptionRange.java
+++ b/game/client/src/main/java/net/minecraft/client/option/OptionRange.java
@@ -5,19 +5,19 @@ import org.jetbrains.annotations.NotNull;
 public class OptionRange extends OptionToggleable<Integer> {
 	public final int highest;
 	public final int lowest;
-    public OptionRange(GameSettings gameSettings, String name, int defaultValue, int values) {
-        super(gameSettings, name, defaultValue, getValueArray(values));
+    public OptionRange(@NotNull String name, int defaultValue, int values) {
+        super(name, defaultValue, getValueArray(values));
         this.highest = this.values[this.values.length - 1];
         this.lowest = this.values[0];
     }
-	public OptionRange(GameSettings gameSettings, String name, int defaultValue, int lowest, int highest) {
-		super(gameSettings, name, defaultValue, getValueArray(lowest, highest));
+	public OptionRange(@NotNull String name, int defaultValue, int lowest, int highest) {
+		super(name, defaultValue, getValueArray(lowest, highest));
 		this.highest = highest;
 		this.lowest = lowest;
 	}
 
 	@Override
-	public void parse(@NotNull String string) {
+	public void fromOptionsString(@NotNull String string) {
 		this.value = Integer.parseInt(string);
 	}
     
diff --git a/game/client/src/main/java/net/minecraft/client/option/OptionString.java b/game/client/src/main/java/net/minecraft/client/option/OptionString.java
index e69745bdb..aa4e17125 100644
--- a/game/client/src/main/java/net/minecraft/client/option/OptionString.java
+++ b/game/client/src/main/java/net/minecraft/client/option/OptionString.java
@@ -4,12 +4,12 @@ import org.jetbrains.annotations.NotNull;
 
 public class OptionString extends Option<String>{
 
-	public OptionString(GameSettings gameSettings, String name, String defaultValue) {
-		super(gameSettings, name, defaultValue);
+	public OptionString(@NotNull String name, @NotNull String defaultValue) {
+		super(name, defaultValue);
 	}
 
 	@Override
-	public void parse(@NotNull String string) {
+	public void fromOptionsString(@NotNull String string) {
 		this.value = string;
 	}
 
diff --git a/game/client/src/main/java/net/minecraft/client/option/OptionToggleable.java b/game/client/src/main/java/net/minecraft/client/option/OptionToggleable.java
index d4dc88641..37242801f 100644
--- a/game/client/src/main/java/net/minecraft/client/option/OptionToggleable.java
+++ b/game/client/src/main/java/net/minecraft/client/option/OptionToggleable.java
@@ -2,39 +2,40 @@ package net.minecraft.client.option;
 
 import net.minecraft.client.render.dynamictexture.DynamicTexture;
 import net.minecraft.core.util.helper.Toggleable;
+import org.jetbrains.annotations.NotNull;
 
 public abstract class OptionToggleable<E> extends Option<E> implements Toggleable{
 
 	public E[] values;
 	
-	public OptionToggleable(GameSettings gameSettings, String name, E defaultValue, E[] values) {
-		super(gameSettings, name, defaultValue);
+	public OptionToggleable(@NotNull String name, @NotNull E defaultValue, E[] values) {
+		super(name, defaultValue);
 		
 		this.values = values;
 	}
 	
 	@Override
 	public void toggle() {
-		this.value = values[(getValueIndex() + 1) % values.length];
+		this.value = this.values[(getValueIndex() + 1) % this.values.length];
 	}
 	
 	public void toggle(int delta) {
-		this.value = values[DynamicTexture.pmod(getValueIndex() + delta, values.length)];
+		this.value = this.values[DynamicTexture.pmod(getValueIndex() + delta, this.values.length)];
 	}
 	
 	public int getValueIndex() {
-		for(int i=0; i < values.length; i++) {
-			if(value == values[i]) return i;
+		for(int i = 0; i < this.values.length; i++) {
+			if(this.value == this.values[i]) return i;
 		}
 		return 0;
 	}
 	
 	public void setValueWithIndex(int i) {
-		this.value = values[i];
+		this.value = this.values[i];
 	}
 	
 	public int size() {
-		return values.length;
+		return this.values.length;
 	}
 	
 	public abstract boolean isSlider();
diff --git a/game/client/src/main/java/net/minecraft/client/option/OptionTooltip.java b/game/client/src/main/java/net/minecraft/client/option/OptionTooltip.java
index 6905430a7..6cf41251b 100644
--- a/game/client/src/main/java/net/minecraft/client/option/OptionTooltip.java
+++ b/game/client/src/main/java/net/minecraft/client/option/OptionTooltip.java
@@ -7,12 +7,12 @@ import org.jetbrains.annotations.NotNull;
 
 public class OptionTooltip extends OptionToggleable<String> implements Toggleable {
 
-    public OptionTooltip(final GameSettings gameSettings, final String name, final String defaultValue) {
-        super(gameSettings, name, defaultValue, null);
+    public OptionTooltip(final @NotNull String name, final @NotNull String defaultValue) {
+        super(name, defaultValue, null);
     }
 
     @Override
-    public void parse(final @NotNull String string) {
+    public void fromOptionsString(final @NotNull String string) {
         this.value = string;
     }
 
diff --git a/game/client/src/main/java/net/minecraft/client/option/OptionVolume.java b/game/client/src/main/java/net/minecraft/client/option/OptionVolume.java
index 159567b38..163a2028b 100644
--- a/game/client/src/main/java/net/minecraft/client/option/OptionVolume.java
+++ b/game/client/src/main/java/net/minecraft/client/option/OptionVolume.java
@@ -1,33 +1,35 @@
 package net.minecraft.client.option;
 
 import com.mojang.logging.LogUtils;
+import net.minecraft.client.Minecraft;
 import net.minecraft.client.sound.SoundCategoryHelper;
 import net.minecraft.client.sound.SoundEngine;
 import net.minecraft.core.sound.SoundCategory;
+import org.jetbrains.annotations.NotNull;
 import org.slf4j.Logger;
 import paulscode.sound.SoundSystem;
 
 public class OptionVolume extends OptionFloat {
 	private static final Logger LOGGER = LogUtils.getLogger();
-	public final SoundCategory soundCategory;
+	public final @NotNull SoundCategory soundCategory;
 
 	//do *not* add @NotNull to gameSettings here, breaks modding for some abstract reason
-	public OptionVolume(GameSettings gameSettings, String name, float value, SoundCategory soundCategory) {
-		super(gameSettings, name, value);
+	public OptionVolume(@NotNull String name, float value, @NotNull SoundCategory soundCategory) {
+		super(name, value);
 		this.soundCategory = soundCategory;
 	}
 	
 	@Override
 	public void onUpdate() {
 		super.onUpdate();
-		gameSettings.mc.sndManager.updateOptions();
+		Minecraft.getMinecraft().sndManager.updateOptions();
 		SoundSystem soundSystem = SoundEngine.getSoundSystem();
 		try {
 			if (soundSystem != null) {
-				if (soundCategory != SoundCategory.GUI_SOUNDS && !soundSystem.playing("sound_audio_options")) {
-					gameSettings.mc.sndManager.playSoundWithID(soundCategory.changedSound, soundCategory, 1f, 1f, "sound_audio_options");
-				} else if (soundCategory != SoundCategory.GUI_SOUNDS) {
-					soundSystem.setVolume("sound_audio_options", SoundCategoryHelper.getEffectiveVolume(soundCategory, gameSettings));
+				if (this.soundCategory != SoundCategory.GUI_SOUNDS && !soundSystem.playing("sound_audio_options")) {
+					Minecraft.getMinecraft().sndManager.playSoundWithID(this.soundCategory.changedSound, this.soundCategory, 1f, 1f, "sound_audio_options");
+				} else if (this.soundCategory != SoundCategory.GUI_SOUNDS) {
+					soundSystem.setVolume("sound_audio_options", SoundCategoryHelper.getEffectiveVolume(this.soundCategory));
 				}
 			}
 		} catch (Exception e) { // Not sure why but this block of code, specifically the `soundSystem.playing("sound_audio_options")` line seems to be able to through an NPE *sometimes* for *some* users.
diff --git a/game/client/src/main/java/net/minecraft/client/option/enums/CloudQuality.java b/game/client/src/main/java/net/minecraft/client/option/enums/CloudQuality.java
new file mode 100644
index 000000000..4868b14cf
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/option/enums/CloudQuality.java
@@ -0,0 +1,6 @@
+package net.minecraft.client.option.enums;
+
+public enum CloudQuality {
+    FAST,
+    FANCY;
+}
diff --git a/game/client/src/main/java/net/minecraft/client/option/enums/DescriptionPromptEnum.java b/game/client/src/main/java/net/minecraft/client/option/enums/DescriptionPromptEnum.java
index 16b1e0b24..faa2db48e 100644
--- a/game/client/src/main/java/net/minecraft/client/option/enums/DescriptionPromptEnum.java
+++ b/game/client/src/main/java/net/minecraft/client/option/enums/DescriptionPromptEnum.java
@@ -1,14 +1,13 @@
 package net.minecraft.client.option.enums;
 
-import net.minecraft.client.Minecraft;
-import org.jetbrains.annotations.NotNull;
+import net.minecraft.client.option.GameSettings;
 
 public enum DescriptionPromptEnum {
     NEVER_PROMPT,
     PROMPT,
     ALWAYS_SHOW;
 
-    public static boolean showDescription(@NotNull final Minecraft minecraft) {
-        return (minecraft.gameSettings.itemDescriptions.value == DescriptionPromptEnum.ALWAYS_SHOW || minecraft.gameSettings.keyDescription.isPressed());
+    public static boolean showDescription() {
+        return (GameSettings.ITEM_DESCRIPTIONS.value == DescriptionPromptEnum.ALWAYS_SHOW || GameSettings.KEY_DESCRIPTION.isPressed());
     }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/option/enums/LeavesQuality.java b/game/client/src/main/java/net/minecraft/client/option/enums/LeavesQuality.java
new file mode 100644
index 000000000..a60a3f3fc
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/option/enums/LeavesQuality.java
@@ -0,0 +1,7 @@
+package net.minecraft.client.option.enums;
+
+public enum LeavesQuality {
+    FAST,
+    SMART,
+    FANCY;
+}
diff --git a/game/client/src/main/java/net/minecraft/client/option/enums/ParticlesQuality.java b/game/client/src/main/java/net/minecraft/client/option/enums/ParticlesQuality.java
new file mode 100644
index 000000000..43fa1a6c5
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/option/enums/ParticlesQuality.java
@@ -0,0 +1,7 @@
+package net.minecraft.client.option.enums;
+
+public enum ParticlesQuality {
+    NONE,
+    REDUCED,
+    ALL,
+}
diff --git a/game/client/src/main/java/net/minecraft/client/option/enums/TextOutlineQuality.java b/game/client/src/main/java/net/minecraft/client/option/enums/TextOutlineQuality.java
new file mode 100644
index 000000000..c4273e351
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/option/enums/TextOutlineQuality.java
@@ -0,0 +1,6 @@
+package net.minecraft.client.option.enums;
+
+public enum TextOutlineQuality {
+    FAST,
+    FANCY;
+}
diff --git a/game/client/src/main/java/net/minecraft/client/option/enums/TextureAnimation.java b/game/client/src/main/java/net/minecraft/client/option/enums/TextureAnimation.java
new file mode 100644
index 000000000..b40e38f34
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/option/enums/TextureAnimation.java
@@ -0,0 +1,7 @@
+package net.minecraft.client.option.enums;
+
+public enum TextureAnimation {
+    OFF,
+    PROCEDURAL,
+    CUSTOM;
+}
diff --git a/game/client/src/main/java/net/minecraft/client/player/controller/PlayerController.java b/game/client/src/main/java/net/minecraft/client/player/controller/PlayerController.java
index 9727b497e..bd72be525 100644
--- a/game/client/src/main/java/net/minecraft/client/player/controller/PlayerController.java
+++ b/game/client/src/main/java/net/minecraft/client/player/controller/PlayerController.java
@@ -123,7 +123,7 @@ public abstract class PlayerController {
                 this.setMineBlock(tilePos);
             }
 
-            Objects.requireNonNull(this.mc.particleEngine).crack(tilePos.x(), tilePos.y(), tilePos.z(), side);
+            Objects.requireNonNull(this.mc.particleEngine).crack(tilePos, side);
             this.playDigSound(mineBlock, tilePos);
 
             this.destroyProgress += mineStrength;
diff --git a/game/client/src/main/java/net/minecraft/client/render/EntityRendererDispatcher.java b/game/client/src/main/java/net/minecraft/client/render/EntityRendererDispatcher.java
index 0b47c55be..dcf353d2f 100644
--- a/game/client/src/main/java/net/minecraft/client/render/EntityRendererDispatcher.java
+++ b/game/client/src/main/java/net/minecraft/client/render/EntityRendererDispatcher.java
@@ -23,7 +23,6 @@ import net.minecraft.core.item.Items;
 import net.minecraft.core.world.World;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
-import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.camera.ICamera;
 import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import net.minecraft.core.entity.Entity;
@@ -45,7 +44,6 @@ public final class EntityRendererDispatcher {
     public final @NotNull TextureManager textureManager;
     public final @NotNull TexturePackList packList;
     public final @NotNull FontRenderer font;
-    public final @NotNull GameSettings settings;
     public float viewLerpYaw = 0;
     public float viewLerpPitch = 0;
     public double viewLerpPosX = 0;
@@ -57,7 +55,6 @@ public final class EntityRendererDispatcher {
         this.textureManager = mc.textureManager;
         this.packList = mc.texturePackList;
         this.font = mc.font;
-        this.settings = mc.gameSettings;
         reload();
     }
 
diff --git a/game/client/src/main/java/net/minecraft/client/render/FogManager.java b/game/client/src/main/java/net/minecraft/client/render/FogManager.java
index a3ab99b23..717428414 100644
--- a/game/client/src/main/java/net/minecraft/client/render/FogManager.java
+++ b/game/client/src/main/java/net/minecraft/client/render/FogManager.java
@@ -2,6 +2,7 @@ package net.minecraft.client.render;
 
 import static net.minecraft.client.render.uniform.UniformBlock.N;
 
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.world.WorldClient;
 import net.minecraft.core.block.material.Materials;
 import net.minecraft.core.world.pos.TilePos;
@@ -43,7 +44,7 @@ public class FogManager {
 
         float brightnessAtCamera = this.mc.currentWorld.getLightBrightness(this.mc.activeCamera.getTilePos());
         if (this.mc.fullbright) brightnessAtCamera = 1.0f;
-        float renderDistanceModifier = (((this.mc.gameSettings.renderDistance.highest - this.mc.gameSettings.renderDistance.value) * fogModifier) / (float) this.mc.gameSettings.renderDistance.highest);
+        float renderDistanceModifier = (((GameSettings.RENDER_DISTANCE.highest - GameSettings.RENDER_DISTANCE.value) * fogModifier) / (float) GameSettings.RENDER_DISTANCE.highest);
 
         float newBrightness = brightnessAtCamera * (1.0F - renderDistanceModifier) + renderDistanceModifier;
 
@@ -62,7 +63,7 @@ public class FogManager {
             cameraState = 0;
         }
 
-        if (!this.mc.gameSettings.fog.value && fogMode != FOG_MODE_SKY && cameraState == 0) {
+        if (!GameSettings.FOG.value && fogMode != FOG_MODE_SKY && cameraState == 0) {
             return dest.disable();
         }
 
@@ -79,7 +80,7 @@ public class FogManager {
             }
             default: {
                 float fogDistance = farPlaneDistance;
-                float maxFogDistance = this.mc.gameSettings.renderDistance.highest * 16;
+                float maxFogDistance = GameSettings.RENDER_DISTANCE.highest * 16;
 
                 float fogModifier = this.mc.currentWorld.getCurrentWeather() != null ? this.mc.currentWorld.getCurrentWeather().getFogDistanceMultiplier() : 1.0f;
                 fogModifier = (1.0f - ((1.0f - fogModifier) * this.mc.currentWorld.weatherManager.getWeatherIntensity() * this.mc.currentWorld.weatherManager.getWeatherPower()));
@@ -109,7 +110,7 @@ public class FogManager {
     public void updateFogColor(float partialTick) {
         WorldClient world = this.mc.currentWorld;
 
-        float renderDistanceScale = 1.0F / (float) ((this.mc.gameSettings.renderDistance.highest + 8) - this.mc.gameSettings.renderDistance.value);
+        float renderDistanceScale = 1.0F / (float) ((GameSettings.RENDER_DISTANCE.highest + 8) - GameSettings.RENDER_DISTANCE.value);
         renderDistanceScale = 1.0F - (float) Math.pow(renderDistanceScale, 0.25D);
 
         Vector3fc skyColor = world.getSkyColor(this.mc.activeCamera, partialTick);
@@ -136,7 +137,7 @@ public class FogManager {
             this.fogRed = 0.02F;
             this.fogGreen = 0.02F;
             this.fogBlue = 0.2F;
-            if (this.mc.gameSettings.biomeWater.value) {
+            if (GameSettings.BIOME_WATER.value) {
                 TilePos cameraTile = this.mc.activeCamera.getTilePos();
                 double temp = world.getBlockTemperature(cameraTile);
                 double humid = world.getBlockHumidity(cameraTile);
@@ -196,7 +197,7 @@ public class FogManager {
         public @NotNull FogState disable() {
             this.fogMode = FogState.Mode.EXP;
             this.fogDensity = 0.0F;
-            float maxFogDistance = Minecraft.getMinecraft().gameSettings.renderDistance.highest * 16;
+            float maxFogDistance = GameSettings.RENDER_DISTANCE.highest * 16;
             this.fogStart = maxFogDistance * 0.25f;
             this.fogEnd = maxFogDistance;
             return this;
diff --git a/game/client/src/main/java/net/minecraft/client/render/LightmapHelper.java b/game/client/src/main/java/net/minecraft/client/render/LightmapHelper.java
index dc821788a..7689e475a 100644
--- a/game/client/src/main/java/net/minecraft/client/render/LightmapHelper.java
+++ b/game/client/src/main/java/net/minecraft/client/render/LightmapHelper.java
@@ -8,6 +8,7 @@ import com.mojang.logging.LogUtils;
 import net.minecraft.client.GLAllocation;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.ScreenPhotoMode;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.option.enums.LightmapStyle;
 import net.minecraft.client.util.helper.Textures;
 import net.minecraft.client.util.helper.Buffer;
@@ -42,7 +43,7 @@ public class LightmapHelper {
 	
 	public void setup() {
 		World world = this.mc.currentWorld;
-		if(this.mc.gameSettings.customLightmap.value && world != null) {
+		if(GameSettings.CUSTOM_LIGHTMAP.value && world != null) {
 			int dimension = world.dimension.id;
 			
 			String path = "/assets/minecraft/textures/environment/lightmap" + dimension + ".png";
@@ -91,10 +92,10 @@ public class LightmapHelper {
 		if(this.mc.fullbright) {
             Arrays.fill(this.lightmapData, 0xFFFFFFFF);
 		} else {
-			if(this.mc.gameSettings.customLightmap.value && this.customLightmap != null) {
+			if(GameSettings.CUSTOM_LIGHTMAP.value && this.customLightmap != null) {
 				generateCustomLightmap(world);
 			}else {
-				LightmapStyle lightmapStyle = this.mc.gameSettings.lightmapStyle.value;
+				LightmapStyle lightmapStyle = GameSettings.LIGHTMAP_STYLE.value;
 				
 				if(lightmapStyle == LightmapStyle.COLORIZED) {
 					generateColorizedLightmap(world, partialTicks);
@@ -126,7 +127,7 @@ public class LightmapHelper {
 	}
 
 	public void generateGrayLightmap(World world, float partialTicks) {
-		boolean smooth = this.mc.gameSettings.ambientOcclusion.value;
+		boolean smooth = GameSettings.AMBIENT_OCCLUSION.value;
 		
 		for(int i = 0; i < 256; i++) {
 			final int skyLightLevel = i / 16;
@@ -148,7 +149,7 @@ public class LightmapHelper {
 				brightness = world.worldType.getBrightnessRamp()[light];
 			}
 			
-			brightness = applyGamma(brightness, this.mc.gameSettings.brightness.value - 0.5f);
+			brightness = applyGamma(brightness, GameSettings.BRIGHTNESS.value - 0.5f);
 			brightness = MathHelper.clamp(brightness, 0.0f, 1.0f);
 
 			int brightnessI = (int) (brightness * 255);
@@ -161,7 +162,7 @@ public class LightmapHelper {
 	
 	public void generateColorizedLightmap(World world, float partialTicks) {
 		float ambientBrightness = world.getAmbientBrightness(partialTicks);
-		float brightness = this.mc.gameSettings.brightness.value - 0.5f;
+		float brightness = GameSettings.BRIGHTNESS.value - 0.5f;
 
 		for(int i = 0; i < 256; i++) {
 			float skyLight = getBrightnessRemoveMinLight(world, i / 16) * (ambientBrightness * 0.95f + 0.05f);
@@ -205,7 +206,7 @@ public class LightmapHelper {
 	
 	public void generateCustomLightmap(World world) {
 		float ambientBrightness = (world.getAmbientBrightness(1.0f) - 0.2f) / 0.8f;
-		float brightness = this.mc.gameSettings.brightness.value;
+		float brightness = GameSettings.BRIGHTNESS.value;
 		
 		int skylightX = MathHelper.floor_float(ambientBrightness * (this.customLightmap.getWidth() - 2));
 		
diff --git a/game/client/src/main/java/net/minecraft/client/render/LoadingScreenRenderer.java b/game/client/src/main/java/net/minecraft/client/render/LoadingScreenRenderer.java
index 01fa9f477..cf5ee91e3 100644
--- a/game/client/src/main/java/net/minecraft/client/render/LoadingScreenRenderer.java
+++ b/game/client/src/main/java/net/minecraft/client/render/LoadingScreenRenderer.java
@@ -55,14 +55,8 @@ public class LoadingScreenRenderer
         String[] split = tip.split(" ");
         for (String s : split) {
             if (s.startsWith("%")) {
-                KeyBinding binding = null;
                 String sub = s.substring(1);
-                for (KeyBinding b : GameSettings.keys) {
-                    if (b.getId().equals(sub)) {
-                        binding = b;
-                        break;
-                    }
-                }
+                KeyBinding binding = GameSettings.getKeyBinding(sub);
                 if (binding != null) {
                     return tip.replace(s, TextFormatting.BOLD + binding.getKeyName() + TextFormatting.RESET);
                 }
diff --git a/game/client/src/main/java/net/minecraft/client/render/OpenGLHelper.java b/game/client/src/main/java/net/minecraft/client/render/OpenGLHelper.java
index fedbe58df..131e4ddf2 100644
--- a/game/client/src/main/java/net/minecraft/client/render/OpenGLHelper.java
+++ b/game/client/src/main/java/net/minecraft/client/render/OpenGLHelper.java
@@ -1,37 +1,46 @@
 package net.minecraft.client.render;
 
-import java.util.HashSet;
-import java.util.Set;
-
 import com.mojang.logging.LogUtils;
+import net.minecraft.client.Minecraft;
 import net.minecraft.core.Global;
 import net.minecraft.core.enums.EnumOS;
 import org.jetbrains.annotations.NotNull;
 import org.lwjgl.opengl.ARBFramebufferObject;
-import org.lwjgl.opengl.ContextCapabilities;
 import org.lwjgl.opengl.GL41;
 import org.lwjgl.opengl.GLCapabilities;
-import org.lwjgl.opengl.GLContext;
-
-import net.minecraft.client.Minecraft;
 import org.slf4j.Logger;
 
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
 public class OpenGLHelper {
     private static final Logger LOGGER = LogUtils.getLogger();
     private static final Set<String> errors = new HashSet<>();
 
     public static int[] versionPairs = new int[] {4, 6, 4, 3, 4, 1};
 
+    public static boolean contextCreated = false;
     public static boolean gl46 = false;
     public static boolean gl43 = false;
 
+    public static @NotNull String version = "Unknown";
+    public static @NotNull String vendor = "Unknown";
+    public static @NotNull String renderer = "Unknown";
+
     public static void testCapabilities(@NotNull GLCapabilities capabilities) {
+        contextCreated = true;
         LOGGER.info("");
         LOGGER.info("=== GPU VENDOR INFO ===");
         LOGGER.info("OpenGL {}.{}", GL41.glGetInteger(GL41.GL_MAJOR_VERSION), GL41.glGetInteger(GL41.GL_MINOR_VERSION));
-        LOGGER.info(GL41.glGetString(GL41.GL_VERSION));
-        LOGGER.info(GL41.glGetString(GL41.GL_VENDOR));
-        LOGGER.info(GL41.glGetString(GL41.GL_RENDERER));
+
+        version = Objects.requireNonNullElse(GL41.glGetString(GL41.GL_VERSION), "Query Failure");
+        vendor = Objects.requireNonNullElse(GL41.glGetString(GL41.GL_VENDOR), "Query Failure");
+        renderer = Objects.requireNonNullElse(GL41.glGetString(GL41.GL_RENDERER), "Query Failure");
+
+        LOGGER.info(version);
+        LOGGER.info(vendor);
+        LOGGER.info(renderer);
 
         LOGGER.info("");
 
@@ -52,19 +61,21 @@ public class OpenGLHelper {
     }
 
     public static void checkError(String info) {
-        int errorCode = GL41.glGetError();
+        if (Global.DEBUG_MODE) {
+            int errorCode = GL41.glGetError();
 
-        if (errorCode != GL41.GL_NO_ERROR) {
-            if (Global.BUILD_CHANNEL.isUnstableBuild()) {
-                String error = errorCode + " (" + getErrorDescription(errorCode) + "): " + info;
-                throw new RuntimeException("OpenGL Error " + error);
-            }
+            if (errorCode != GL41.GL_NO_ERROR) {
+                if (Global.BUILD_CHANNEL.isUnstableBuild()) {
+                    String error = errorCode + " (" + getErrorDescription(errorCode) + "): " + info;
+                    throw new RuntimeException("OpenGL Error " + error);
+                }
 
-            if (!errors.contains(info)) {
-                errors.add(info);
-                String error = errorCode + " (" + getErrorDescription(errorCode) + "): " + info;
-                LOGGER.error("########## GL ERROR ##########");
-                LOGGER.error("OpenGL Error {}", error);
+                if (!errors.contains(info)) {
+                    errors.add(info);
+                    String error = errorCode + " (" + getErrorDescription(errorCode) + "): " + info;
+                    LOGGER.error("########## GL ERROR ##########");
+                    LOGGER.error("OpenGL Error {}", error);
+                }
             }
         }
     }
diff --git a/game/client/src/main/java/net/minecraft/client/render/ParticleEngine.java b/game/client/src/main/java/net/minecraft/client/render/ParticleEngine.java
index 0254e9be9..6f3fa2e70 100644
--- a/game/client/src/main/java/net/minecraft/client/render/ParticleEngine.java
+++ b/game/client/src/main/java/net/minecraft/client/render/ParticleEngine.java
@@ -1,28 +1,31 @@
 package net.minecraft.client.render;
 
-import java.util.*;
-
 import it.unimi.dsi.fastutil.objects.ObjectArrayList;
+import net.minecraft.client.option.GameSettings;
+import net.minecraft.client.option.enums.ParticlesQuality;
 import net.minecraft.client.render.camera.ICamera;
-import net.minecraft.client.render.particle.ParticleBlockBreaking;
 import net.minecraft.client.render.particle.Particle;
+import net.minecraft.client.render.particle.ParticleBlockBreaking;
 import net.minecraft.client.render.renderer.BlendFactor;
 import net.minecraft.client.render.renderer.CompareFunc;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.Shaders;
 import net.minecraft.client.render.renderer.State;
+import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import net.minecraft.client.render.tessellator.TessellatorParticle;
 import net.minecraft.client.render.tessellator.TessellatorParticleShader;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.client.render.tessellator.TessellatorGeneral;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.world.World;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.Blocks;
-import net.minecraft.core.world.pos.TilePos;
+import net.minecraft.core.util.helper.Side;
+import net.minecraft.core.world.World;
+import net.minecraft.core.world.pos.TilePosc;
 import org.jetbrains.annotations.NotNull;
 import org.joml.primitives.AABBdc;
 
+import java.util.List;
+import java.util.Random;
+
 /**
  * Handles rendering and ticking of client-side particles.
  */
@@ -54,7 +57,7 @@ public final class ParticleEngine {
      */
     public void add(Particle p) {
         int t = p.getParticleTexture();
-        if (this.particles[t].size() >= 4000) {
+        if (this.particles[t].size() >= GameSettings.PARTICLES_CAP.value) {
             this.particles[t].remove(0);
         }
         this.particles[t].add(p);
@@ -152,27 +155,26 @@ public final class ParticleEngine {
     /**
      * Produces a burst of terrain particles at the location a block is destroyed.
      *
-     * @param x    The X coordinate of the destroyed block.
-     * @param y    The Y coordinate of the destroyed block.
-     * @param z    The Z coordinate of the destroyed block.
+     * @param blockPos The coordinate of the destroyed block.
      * @param id   The ID of the destroyed block.
      * @param data The metadata value of the destroyed block.
      */
-    public void destroy(int x, int y, int z, int id, int data) {
+    public void destroy(@NotNull TilePosc blockPos, int id, int data) {
+        if (GameSettings.PARTICLES_QUALITY.value == ParticlesQuality.NONE) return;
         Block<?> block = Blocks.blocksList[id];
         if (block == null) return;
-        int amount = 4;
+        int amount = GameSettings.PARTICLES_QUALITY.value == ParticlesQuality.REDUCED ? 2 : 4;
         if (block == Blocks.FIRE) {
             return;
         }
         for (int xx = 0; xx < amount; xx++) {
             for (int yy = 0; yy < amount; yy++) {
                 for (int zz = 0; zz < amount; zz++) {
-                    double xp = x + (xx + 0.5D) / amount;
-                    double yp = y + (yy + 0.5D) / amount;
-                    double zp = z + (zz + 0.5D) / amount;
+                    double xp = blockPos.x() + (xx + 0.5D) / amount;
+                    double yp = blockPos.y() + (yy + 0.5D) / amount;
+                    double zp = blockPos.z() + (zz + 0.5D) / amount;
                     Side side = Side.getSideById(this.rand.nextInt(6));
-                    add((new ParticleBlockBreaking(this.world, xp, yp, zp, xp - x - 0.5D, yp - y - 0.5D, zp - z - 0.5D, block, side, data)).init(new TilePos(x, y, z)));
+                    add((new ParticleBlockBreaking(this.world, xp, yp, zp, xp - blockPos.x() - 0.5D, yp - blockPos.y() - 0.5D, zp - blockPos.z() - 0.5D, block, side, data)).init(blockPos));
                 }
             }
         }
@@ -181,36 +183,34 @@ public final class ParticleEngine {
     /**
      * Produces falling terrain particles along the side of a block.
      *
-     * @param x    The X coordinate of the block.
-     * @param y    The Y coordinate of the block.
-     * @param z    The Z coordinate of the block.
+     * @param blockPos The coordinate of the block.
      * @param side The side along which to produce particles.
      */
-    public void crack(int x, int y, int z, Side side) {
-        int id = this.world.getBlockId(x, y, z);
-        if (id == 0) {
+    public void crack(@NotNull TilePosc blockPos, @NotNull Side side) {
+        if (GameSettings.PARTICLES_QUALITY.value == ParticlesQuality.NONE) return;
+        Block<?> block = this.world.getBlockType(blockPos);
+        if (block == Blocks.AIR) {
             return;
         }
-        Block<?> block = Blocks.blocksList[id];
         AABBdc bounds = block.getBounds();
         float r = 0.1F;
-        double xp = x + this.rand.nextDouble() * (bounds.maxX() - bounds.minX() - (r * 2.0F)) + r + bounds.minX();
-        double yp = y + this.rand.nextDouble() * (bounds.maxY() - bounds.minY() - (r * 2.0F)) + r + bounds.minY();
-        double zp = z + this.rand.nextDouble() * (bounds.maxZ() - bounds.minZ() - (r * 2.0F)) + r + bounds.minZ();
+        double xp = blockPos.x() + this.rand.nextDouble() * (bounds.maxX() - bounds.minX() - (r * 2.0F)) + r + bounds.minX();
+        double yp = blockPos.y() + this.rand.nextDouble() * (bounds.maxY() - bounds.minY() - (r * 2.0F)) + r + bounds.minY();
+        double zp = blockPos.z() + this.rand.nextDouble() * (bounds.maxZ() - bounds.minZ() - (r * 2.0F)) + r + bounds.minZ();
         if (side == Side.BOTTOM) {
-            yp = (y + bounds.minY()) - r;
+            yp = (blockPos.y() + bounds.minY()) - r;
         } else if (side == Side.TOP) {
-            yp = (y + bounds.maxY()) + r;
+            yp = (blockPos.y() + bounds.maxY()) + r;
         } else if (side == Side.NORTH) {
-            zp = (z + bounds.minZ()) - r;
+            zp = (blockPos.z() + bounds.minZ()) - r;
         } else if (side == Side.SOUTH) {
-            zp = (z + bounds.maxZ()) + r;
+            zp = (blockPos.z() + bounds.maxZ()) + r;
         } else if (side == Side.WEST) {
-            xp = (x + bounds.minX()) - r;
+            xp = (blockPos.x() + bounds.minX()) - r;
         } else if (side == Side.EAST) {
-            xp = x + bounds.maxX() + r;
+            xp = blockPos.x() + bounds.maxX() + r;
         }
-        add((new ParticleBlockBreaking(this.world, xp, yp, zp, 0.0D, 0.0D, 0.0D, block, side, this.world.getBlockMetadata(x, y, z))).init(new TilePos(x, y, z)).setPower(0.2F).setScale(0.6F));
+        add((new ParticleBlockBreaking(this.world, xp, yp, zp, 0.0D, 0.0D, 0.0D, block, side, this.world.getBlockData(blockPos))).init(blockPos).setPower(0.2F).setScale(0.6F));
     }
 
     public int countParticles() {
diff --git a/game/client/src/main/java/net/minecraft/client/render/PostProcessingManager.java b/game/client/src/main/java/net/minecraft/client/render/PostProcessingManager.java
index dbf608462..5ba74f788 100644
--- a/game/client/src/main/java/net/minecraft/client/render/PostProcessingManager.java
+++ b/game/client/src/main/java/net/minecraft/client/render/PostProcessingManager.java
@@ -1,8 +1,10 @@
 package net.minecraft.client.render;
 
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.Dimension;
+import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.type.WorldTypes;
 import net.minecraft.core.world.season.Seasons;
 import net.minecraft.core.world.weather.Weather;
@@ -67,7 +69,7 @@ public class PostProcessingManager {
         if (this.mc.currentWorld == null || this.mc.thePlayer == null) return;
 
         this.reset();
-        if (this.mc.gameSettings.colorCorrection.value == 0) return;
+        if (GameSettings.COLOR_CORRECTION.value == 0) return;
 
         final float y = (float) this.mc.thePlayer.y;
         final int maxY = this.mc.currentWorld.getWorldType().getMaxY();
@@ -81,11 +83,11 @@ public class PostProcessingManager {
         float surfaceness = adjustedY / hToQRange;
         surfaceness = MathHelper.clamp(surfaceness, 0.0f, 1.0f);
 
-        double t = this.mc.currentWorld.getBlockTemperature((int) this.mc.thePlayer.x, (int) this.mc.thePlayer.z); // Ranges from 0.0 to 1.0
+        double t = this.mc.currentWorld.getBlockTemperature(new TilePos(this.mc.thePlayer)); // Ranges from 0.0 to 1.0
         if (t == Double.NEGATIVE_INFINITY) t = this.lastTemperature;
         final double temperature = t;
         this.lastTemperature = temperature;
-        double h = this.mc.currentWorld.getBlockHumidity((int) this.mc.thePlayer.x, (int) this.mc.thePlayer.z); // Ranges from 0.0 to 1.0
+        double h = this.mc.currentWorld.getBlockHumidity(new TilePos(this.mc.thePlayer)); // Ranges from 0.0 to 1.0
         if (h == Double.NEGATIVE_INFINITY) h = this.lastHumidity;
         final double humidity = h;
         this.lastHumidity = humidity;
@@ -144,7 +146,7 @@ public class PostProcessingManager {
                 this.current.bMod += 0.1f * intensity * surfaceness;
                 this.current.saturation += -0.2f * intensity * surfaceness;
                 this.current.brightness += -0.1f * intensity * surfaceness;
-            } else if (activeWeather == Weathers.OVERWORLD_FOG && this.mc.gameSettings.fog.value) {
+            } else if (activeWeather == Weathers.OVERWORLD_FOG && GameSettings.FOG.value) {
                 this.current.saturation += -0.4f * intensity * surfaceness;
                 this.current.contrast += -0.25f * intensity * surfaceness;
             }
@@ -177,14 +179,14 @@ public class PostProcessingManager {
         }
 
         // Scaling
-        if (this.mc.gameSettings.colorCorrection.value != 0) {
-            this.current.brightness *= this.mc.gameSettings.colorCorrection.value;
-            this.current.contrast *= this.mc.gameSettings.colorCorrection.value;
-            this.current.exposure *= this.mc.gameSettings.colorCorrection.value;
-            this.current.saturation *= this.mc.gameSettings.colorCorrection.value;
-            this.current.rMod = 1.0f - (1.0f - this.current.rMod) * this.mc.gameSettings.colorCorrection.value;
-            this.current.gMod = 1.0f - (1.0f - this.current.gMod) * this.mc.gameSettings.colorCorrection.value;
-            this.current.bMod = 1.0f - (1.0f - this.current.bMod) * this.mc.gameSettings.colorCorrection.value;
+        if (GameSettings.COLOR_CORRECTION.value != 0) {
+            this.current.brightness *= GameSettings.COLOR_CORRECTION.value;
+            this.current.contrast *= GameSettings.COLOR_CORRECTION.value;
+            this.current.exposure *= GameSettings.COLOR_CORRECTION.value;
+            this.current.saturation *= GameSettings.COLOR_CORRECTION.value;
+            this.current.rMod = 1.0f - (1.0f - this.current.rMod) * GameSettings.COLOR_CORRECTION.value;
+            this.current.gMod = 1.0f - (1.0f - this.current.gMod) * GameSettings.COLOR_CORRECTION.value;
+            this.current.bMod = 1.0f - (1.0f - this.current.bMod) * GameSettings.COLOR_CORRECTION.value;
         }
 
         this.current.brightness = smoothLerp(this.oldCurrent.brightness, this.current.brightness);
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 964fcc095..f96016852 100644
--- a/game/client/src/main/java/net/minecraft/client/render/RenderGlobal.java
+++ b/game/client/src/main/java/net/minecraft/client/render/RenderGlobal.java
@@ -2,19 +2,21 @@ package net.minecraft.client.render;
 
 import it.unimi.dsi.fastutil.objects.ObjectArrayList;
 import net.minecraft.client.Minecraft;
-import net.minecraft.client.render.block.model.generic.BlockModelGenericLeaves;
-import net.minecraft.client.render.particle.Particle;
-import net.minecraft.client.render.particle.ParticleDispatcher;
 import net.minecraft.client.gui.ScreenPhotoMode;
 import net.minecraft.client.gui.modelviewer.ScreenModelViewer;
 import net.minecraft.client.gui.options.ScreenOptions;
+import net.minecraft.client.option.GameSettings;
+import net.minecraft.client.option.enums.CloudQuality;
+import net.minecraft.client.option.enums.ParticlesQuality;
 import net.minecraft.client.render.block.model.BlockModelDispatcher;
 import net.minecraft.client.render.camera.EntityCamera;
 import net.minecraft.client.render.camera.ICamera;
 import net.minecraft.client.render.colorizer.Colorizers;
 import net.minecraft.client.render.culling.CameraFrustum;
+import net.minecraft.client.render.particle.Particle;
+import net.minecraft.client.render.particle.ParticleDispatcher;
+import net.minecraft.client.render.particle.ParticleEntry;
 import net.minecraft.client.render.renderer.BlendFactor;
-import net.minecraft.client.render.renderer.CompareFunc;
 import net.minecraft.client.render.renderer.DrawMode;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.Shaders;
@@ -22,32 +24,32 @@ import net.minecraft.client.render.renderer.State;
 import net.minecraft.client.render.terrain.ChunkRenderer;
 import net.minecraft.client.render.tessellator.RenderBuffer;
 import net.minecraft.client.render.tessellator.TessellatorAurora;
+import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import net.minecraft.client.render.tessellator.TessellatorShader;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
-import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import net.minecraft.client.render.worldtype.WorldTypeFX;
 import net.minecraft.client.render.worldtype.WorldTypeFXDispatcher;
 import net.minecraft.client.world.WorldClient;
+import net.minecraft.core.block.Block;
+import net.minecraft.core.block.Blocks;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.block.support.ISupport;
 import net.minecraft.core.block.support.PartialSupport;
+import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
+import net.minecraft.core.enums.EnumBlockSoundEffectType;
+import net.minecraft.core.item.Item;
 import net.minecraft.core.item.ItemDiscMusic;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.player.gamemode.Gamemodes;
+import net.minecraft.core.sound.SoundCategory;
 import net.minecraft.core.util.helper.Color;
 import net.minecraft.core.util.helper.Direction;
-import net.minecraft.core.util.helper.Side;
-import net.minecraft.core.util.phys.HitResult;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.block.Blocks;
-import net.minecraft.core.entity.Entity;
-import net.minecraft.core.enums.EnumBlockSoundEffectType;
-import net.minecraft.core.item.Item;
-import net.minecraft.core.sound.SoundCategory;
 import net.minecraft.core.util.helper.MathHelper;
+import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.util.phys.BoundingVolume;
+import net.minecraft.core.util.phys.HitResult;
 import net.minecraft.core.world.AuroraProvider;
 import net.minecraft.core.world.LevelListener;
 import net.minecraft.core.world.pos.ChunkPos;
@@ -64,7 +66,10 @@ import org.joml.primitives.AABBd;
 import org.joml.primitives.AABBdc;
 import org.lwjgl.opengl.GL41;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
 
 import static java.awt.Color.HSBtoRGB;
 
@@ -79,8 +84,6 @@ public class RenderGlobal
     }
 
     public static final int RENDER_CHUNK_SIZE = 16;
-    public static final int MAX_VISIBLE_REBUILDS_PER_FRAME = 6;
-    public static final int MAX_INVISIBLE_REBUILDS_PER_FRAME = 1;
 
     public List<TileEntity> renderableTileEntities = new ObjectArrayList<>();
     private WorldClient world;
@@ -229,8 +232,7 @@ public class RenderGlobal
     public void allChanged() {
         ScreenOptions.queueReload = false;
         updateStars();
-        BlockModelGenericLeaves.setGraphicsLevel(this.mc.gameSettings.fancyGraphics.value == 1);
-        this.renderDistance = this.mc.gameSettings.renderDistance.value;
+        this.renderDistance = GameSettings.RENDER_DISTANCE.value;
         if (this.world == null) return;
 
         // Reset all world renderers
@@ -294,7 +296,7 @@ public class RenderGlobal
     }
     private final TessellatorAurora tessellatorAurora = new TessellatorAurora("Aurora Tessellator", 524288);
     public @Nullable RenderBuffer meshAurora(@NotNull ICamera camera) {
-        if (!this.mc.gameSettings.aurora.value) return null;
+        if (!GameSettings.AURORA.value) return null;
         float celestialAngle = this.world.getCelestialAngle(1f);
         float celestialAngleO = this.world.getCelestialAngle(0);
         if (celestialAngle < 0.25f && celestialAngleO < 0.25f) return null;
@@ -512,7 +514,7 @@ public class RenderGlobal
                 }
             }
             if (this.mc.thePlayer.vehicle != entity) {
-                if (!entity.shouldRender(cameraPos, this.mc.gameSettings.entityRenderDistance.value)) continue;
+                if (!entity.shouldRender(cameraPos, GameSettings.ENTITY_RENDER_DISTANCE.value)) continue;
                 if (!entity.ignoreFrustumCheck && !camera.getFrustum().isVisible(EntityRendererDispatcher.instance.getRenderer(entity).entityViewBox(entity), partialTick))
                     continue; // TODO OPENGL fix this broken check, nearly always returns false now
             }
@@ -627,7 +629,7 @@ public class RenderGlobal
             }
         }
 
-        if (this.mc.gameSettings.renderDistance.value != this.renderDistance) {
+        if (GameSettings.RENDER_DISTANCE.value != this.renderDistance) {
             allChanged();
         }
 
@@ -851,7 +853,7 @@ public class RenderGlobal
     }
 
     private float getCloudHeightModifier() {
-        return this.mc.gameSettings.cloudHeight.value * 128;
+        return GameSettings.CLOUD_HEIGHT.value * 128;
     }
 
     public void renderClouds(float partialTick) {
@@ -862,7 +864,7 @@ public class RenderGlobal
         if (this.mc.currentScreen instanceof ScreenPhotoMode) {
             return;
         }
-        if (this.mc.gameSettings.fancyGraphics.value == 1) {
+        if (GameSettings.CLOUD_QUALITY.value == CloudQuality.FANCY) {
             renderCloudsFancy(partialTick);
             return;
         }
@@ -1082,7 +1084,7 @@ public class RenderGlobal
 //        return this.dirtyChunks.size() <= this.cantBuildRenderers.size(); // Return true if no more dirty renderers
 //    }
 
-    private final @Nullable ChunkRenderer @NotNull [] toAdd = new ChunkRenderer[MAX_VISIBLE_REBUILDS_PER_FRAME];
+    private final @Nullable ChunkRenderer @NotNull [] toAdd = new ChunkRenderer[GameSettings.CHUNK_REBUILDS_PER_FRAME.highest];
     private final @NotNull List<@NotNull ChunkRenderer> nearChunks = new ArrayList<>();
 
     public boolean updateDirtyChunks(@NotNull ICamera camera) {
@@ -1098,7 +1100,7 @@ public class RenderGlobal
             if (renderer.distanceToCameraSquared(camera) > nearCheck) {
                 int index = 0;
 
-                while (index < MAX_VISIBLE_REBUILDS_PER_FRAME && (this.toAdd[index] == null || this.dirtyChunkRendererSorter.compare(this.toAdd[index], renderer) <= 0)) {
+                while (index < GameSettings.CHUNK_REBUILDS_PER_FRAME.value && (this.toAdd[index] == null || this.dirtyChunkRendererSorter.compare(this.toAdd[index], renderer) <= 0)) {
                     index++;
                 }
 
@@ -1129,12 +1131,12 @@ public class RenderGlobal
             }
         }
 
-        for (int i = MAX_VISIBLE_REBUILDS_PER_FRAME - 1; i >= 0; i--) {
+        for (int i = GameSettings.CHUNK_REBUILDS_PER_FRAME.value - 1; i >= 0; i--) {
             ChunkRenderer chunkx = this.toAdd[i];
             if (chunkx == null) {
                 continue;
             }
-            if (!chunkx.visible && i != MAX_VISIBLE_REBUILDS_PER_FRAME - 1) {
+            if (!chunkx.visible && i != GameSettings.CHUNK_REBUILDS_PER_FRAME.value - 1) {
                 this.toAdd[i] = null;
                 break;
             }
@@ -1183,7 +1185,7 @@ public class RenderGlobal
     }
 
     public void drawSelectionBox(ICamera camera, HitResult hitResult, float partialTick) {
-        if (this.mc.gameSettings.immersiveMode.drawOutline() && this.mc.gameSettings.blockOutlineWidth.value > 0.01f && !(this.mc.currentScreen instanceof ScreenModelViewer)) {
+        if (GameSettings.IMMERSIVE_MODE.drawOutline() && GameSettings.BLOCK_OUTLINE_WIDTH.value > 0.01f && !(this.mc.currentScreen instanceof ScreenModelViewer)) {
             GLRenderer.pushFrame();
             GLRenderer.enableState(State.BLEND);
             GLRenderer.setBlendFunc(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA);
@@ -1208,7 +1210,7 @@ public class RenderGlobal
                         selectionBB.translate(-offsetX, -offsetY, -offsetZ);
                         drawOutlinedBoundingBox(selectionBB);
                     }
-                    if (this.mc.gameSettings.viewSupportMode.value) {
+                    if (GameSettings.VIEW_SUPPORT_MODE.value) {
                         TessellatorGeneral t = GLRenderer.getTessellator();
 
                         double x = hitTile.tilePos.x() - offsetX;
@@ -1542,7 +1544,7 @@ public class RenderGlobal
                         t.draw();
                     }
                 }
-            } else if (hitResult instanceof HitResult.Entity hitEntity && hitEntity.entity.showBoundingBoxOnHover() && !this.mc.gameSettings.showCollisionBoxes.value) {
+            } else if (hitResult instanceof HitResult.Entity hitEntity && hitEntity.entity.showBoundingBoxOnHover() && !GameSettings.SHOW_COLLISION_BOXES.value) {
                 drawInterpolatedEntityBoundingBox(hitEntity.entity, hitEntity.entity.bb, camera, partialTick);
             }
             GLRenderer.popFrame();
@@ -1839,15 +1841,19 @@ public class RenderGlobal
         if (this.mc == null || this.mc.activeCamera == null || this.mc.particleEngine == null) {
             return;
         }
-        double d6 = this.mc.activeCamera.getX() - x;
-        double d7 = this.mc.activeCamera.getY() - y;
-        double d8 = this.mc.activeCamera.getZ() - z;
-        if (d6 * d6 + d7 * d7 + d8 * d8 > maxDistance * maxDistance) {
+        if (GameSettings.PARTICLES_QUALITY.value == ParticlesQuality.NONE) return;
+        double dx = this.mc.activeCamera.getX() - x;
+        double dy = this.mc.activeCamera.getY() - y;
+        double dz = this.mc.activeCamera.getZ() - z;
+        if (dx * dx + dy * dy + dz * dz > maxDistance * maxDistance * GameSettings.PARTICLE_RENDER_DISTANCE.value * GameSettings.PARTICLE_RENDER_DISTANCE.value) {
             return;
         }
-        Particle fx = ParticleDispatcher.getInstance().getDispatch(particleId).newParticle(this.world, x, y, z, motionX, motionY, motionZ, data);
-        if (fx != null) {
-            this.mc.particleEngine.add(fx);
+        ParticleEntry entry = ParticleDispatcher.getInstance().getDispatch(particleId);
+        if (entry.enabled()) {
+            Particle fx = entry.newParticle(this.world, x, y, z, motionX, motionY, motionZ, data);
+            if (fx != null) {
+                this.mc.particleEngine.add(fx);
+            }
         }
     }
 
@@ -1858,7 +1864,7 @@ public class RenderGlobal
         }
         if (seasonChanged) {
             for (ChunkRenderer chunkRenderer : this.chunkRenderers) {
-                if (chunkRenderer.skyLit && !chunkRenderer.dirty) {
+                if (/*chunkRenderer.skyLit && */!chunkRenderer.dirty) {
                     this.dirtyChunks.add(chunkRenderer);
                     chunkRenderer.setDirty();
                 }
@@ -1913,7 +1919,7 @@ public class RenderGlobal
 
                     this.world.playBlockSoundEffect(null, (float) x + 0.5F, (float) y + 0.5F, (float) z + 0.5F, block, EnumBlockSoundEffectType.MINE);
                 }
-                this.mc.particleEngine.destroy(x, y, z, data, this.world.getBlockMetadata(x, y, z));
+                this.mc.particleEngine.destroy(new TilePos(x, y, z), data, this.world.getBlockMetadata(x, y, z));
                 break;
 
             case EVENT_DOOR_SOUND: // Door sound
diff --git a/game/client/src/main/java/net/minecraft/client/render/TextureManager.java b/game/client/src/main/java/net/minecraft/client/render/TextureManager.java
index 198198164..521dad50d 100644
--- a/game/client/src/main/java/net/minecraft/client/render/TextureManager.java
+++ b/game/client/src/main/java/net/minecraft/client/render/TextureManager.java
@@ -22,6 +22,7 @@ import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.popup.PopupScreen;
 import net.minecraft.client.gui.popup.PopupBuilder;
 import net.minecraft.client.option.GameSettings;
+import net.minecraft.client.option.enums.TextureAnimation;
 import net.minecraft.client.render.colorizer.Colorizers;
 import net.minecraft.client.render.customatlas.CustomAtlasHandler;
 import net.minecraft.client.render.dynamictexture.DynamicTexture;
@@ -72,21 +73,19 @@ public class TextureManager {
 	public final List<TextureBuffered> bufferedTextures = new ObjectArrayList<>();
 	public final Map<String, TextureDownloaded> downloadedTextures = new Object2ObjectOpenHashMap<>();
 	public final Map<NamespaceID, DynamicTexture> dynamicTextures = new Object2ObjectOpenHashMap<>();
-	
-	private final GameSettings gameSettings;
-	public TexturePackList texturePacks;
+
+	public final @NotNull TexturePackList texturePacks;
 	
 	private final boolean clampTexture;
 	private final boolean blurTexture;
 
-	public TextureManager(final Minecraft minecraft, final TexturePackList texturePacks, final GameSettings gameSettings) {
+	public TextureManager(final @NotNull Minecraft minecraft, final @NotNull TexturePackList texturePacks) {
 		this.mc = minecraft;
 		
 		this.clampTexture = false;
 		this.blurTexture = false;
 		
 		this.texturePacks = texturePacks;
-		this.gameSettings = gameSettings;
 	}
 	
 	public void initDynamicTextures(final Collection<? super Throwable> errors) {
@@ -94,8 +93,8 @@ public class TextureManager {
 
         this.dynamicTextures.clear();
 
-		addNativeDynamicTextures(this.mc.gameSettings.animations.value);
-		if (this.mc.gameSettings.customAnimations.value && this.mc.gameSettings.animations.value == ANIMATIONS_CUSTOM) {
+		addNativeDynamicTextures(GameSettings.TEXTURE_ANIMATIONS.value);
+		if (GameSettings.CUSTOM_TEXTURE_ANIMATIONS.value && GameSettings.TEXTURE_ANIMATIONS.value == TextureAnimation.CUSTOM) {
 			try {
 				loadCustomAnimations(errors);
 			}catch (final TexturePackException e) {
@@ -108,8 +107,8 @@ public class TextureManager {
 		addDynamicTextureOverride(new DynamicTextureCompass(this.mc, TextureRegistry.getTexture("minecraft:item/tool_compass")), true);
 	}
 
-	protected void addNativeDynamicTextures(int state) {
-		if (state > ANIMATIONS_DISABLED) {addDynamicTexture(new DynamicTextureWaterStill(TextureRegistry.getTexture("minecraft:block/water_still")));
+	protected void addNativeDynamicTextures(@NotNull TextureAnimation state) {
+		if (state != TextureAnimation.OFF) {addDynamicTexture(new DynamicTextureWaterStill(TextureRegistry.getTexture("minecraft:block/water_still")));
 			addDynamicTexture(new DynamicTextureWaterFlow(TextureRegistry.getTexture("minecraft:block/water_flowing")));
 			addDynamicTexture(new DynamicTextureLavaStill(TextureRegistry.getTexture("minecraft:block/lava_still")));
 			addDynamicTexture(new DynamicTextureLavaFlowing(TextureRegistry.getTexture("minecraft:block/lava_flowing")));
@@ -124,7 +123,7 @@ public class TextureManager {
 			addDynamicTexture(new DynamicTextureTrommel(this.mc, TextureRegistry.getTexture("minecraft:block/trommel/active_front"), true));
 			addDynamicTexture(new DynamicTextureTrommel(this.mc, TextureRegistry.getTexture("minecraft:block/trommel/active_back"), false));
 		}
-		if (state < ANIMATIONS_CUSTOM) {
+		if (state != TextureAnimation.CUSTOM) {
 			for (final DyeColor c : DyeColor.values()) {
 				final IconCoordinate cNether = TextureRegistry.getTexture("minecraft:block/portal_nether/" + c.colorID);
 				assert cNether.hasMeta("animation") : "Coordinate " + cNether.namespaceId + " is expected to have animation data attached!";
@@ -146,7 +145,7 @@ public class TextureManager {
 	}
 
 	private void loadCustomAnimations(final Collection<? super Throwable> errors) {
-		if(!this.mc.gameSettings.customAnimations.value) {
+		if(!GameSettings.CUSTOM_TEXTURE_ANIMATIONS.value) {
 			return;
 		}
 
@@ -229,7 +228,7 @@ public class TextureManager {
 		int y1 = icon.iconY;
 		glTexSubImage2D(GL_TEXTURE_2D, 0, x1, y1, icon.width, icon.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
 		
-		if(this.mc.gameSettings.mipmapLevels.value > 0 && anim.targetTexture.parentAtlas.hasMipmaps()) {
+		if(GameSettings.MIPMAP_LEVELS.value > 0 && anim.targetTexture.parentAtlas.hasMipmaps()) {
 			int levels = glGetTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL);
 
 			for(int level = 1; level <= levels; level++) {
diff --git a/game/client/src/main/java/net/minecraft/client/render/TileEntityRenderDispatcher.java b/game/client/src/main/java/net/minecraft/client/render/TileEntityRenderDispatcher.java
index ac82c1181..b31fd88ca 100644
--- a/game/client/src/main/java/net/minecraft/client/render/TileEntityRenderDispatcher.java
+++ b/game/client/src/main/java/net/minecraft/client/render/TileEntityRenderDispatcher.java
@@ -16,8 +16,7 @@ import net.minecraft.core.world.World;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-public final class TileEntityRenderDispatcher
-{
+public final class TileEntityRenderDispatcher {
     public static final @NotNull TileEntityRenderDispatcher instance = new TileEntityRenderDispatcher();
     public static double renderPosX = 0;
     public static double renderPosY = 0;
@@ -28,7 +27,6 @@ public final class TileEntityRenderDispatcher
     public final @NotNull TextureManager textureManager;
     public final @NotNull TexturePackList packList;
     private final @NotNull FontRenderer font;
-    public final @NotNull GameSettings settings;
     public @Nullable ICamera camera;
     public float viewLerpYaw = 0;
     public float viewLerpPitch = 0;
@@ -37,13 +35,11 @@ public final class TileEntityRenderDispatcher
     public double viewLerpPosZ = 0;
 
 
-    private TileEntityRenderDispatcher()
-    {
+    private TileEntityRenderDispatcher() {
         final Minecraft mc = Minecraft.getMinecraft();
         this.textureManager = mc.textureManager;
         this.packList = mc.texturePackList;
         this.font = mc.font;
-        this.settings = mc.gameSettings;
         this.renderers = new HashMap<>();
         reload();
     }
@@ -66,36 +62,28 @@ public final class TileEntityRenderDispatcher
     }
 
     @SuppressWarnings("unchecked") // trust me this is safe, Notch did it first
-    public <T extends TileEntity> TileEntityRenderer<T> getRenderer(final Class<? extends TileEntity> e)
-    {
+    public <T extends TileEntity> TileEntityRenderer<T> getRenderer(final Class<? extends TileEntity> e) {
         TileEntityRenderer<? extends TileEntity> r = this.renderers.get(e);
-        if(r == null && e != TileEntity.class)
-        {
+        if (r == null && e != TileEntity.class) {
             r = getRenderer((Class<? extends TileEntity>) e.getSuperclass());
             this.renderers.put(e, r);
         }
         return (TileEntityRenderer<T>) r;
     }
 
-    public <T extends TileEntity> @Nullable TileEntityRenderer<T> getRenderer(final @Nullable T tileEntity)
-    {
-        if(tileEntity == null)
-        {
+    public <T extends TileEntity> @Nullable TileEntityRenderer<T> getRenderer(final @Nullable T tileEntity) {
+        if (tileEntity == null) {
             return null;
-        }
-        else
-        {
+        } else {
             return getRenderer(tileEntity.getClass());
         }
     }
 
-    public <T extends TileEntity> boolean hasRenderer(final @NotNull T tileEntity)
-    {
+    public <T extends TileEntity> boolean hasRenderer(final @NotNull T tileEntity) {
         return getRenderer(tileEntity) != null;
     }
 
-    public void cacheActiveRenderInfo(final @NotNull ICamera camera, final float partialTick)
-    {
+    public void cacheActiveRenderInfo(final @NotNull ICamera camera, final float partialTick) {
         this.camera = camera;
         this.viewLerpYaw = (float) camera.getYRot(partialTick);
         this.viewLerpPitch = (float) camera.getXRot(partialTick);
@@ -111,28 +99,26 @@ public final class TileEntityRenderDispatcher
         }
     }
 
-    public <T extends TileEntity> void renderTileEntity(final @NotNull TessellatorGeneral tessellator, final @NotNull ICamera camera, final @NotNull World world, final @NotNull T tileEntity, final float partialTick)
-    {
+    public <T extends TileEntity> void renderTileEntity(final @NotNull TessellatorGeneral tessellator, final @NotNull ICamera camera, final @NotNull World world, final @NotNull T tileEntity, final float partialTick) {
         final TileEntityRenderer<T> renderer = TileEntityRenderDispatcher.instance.getRenderer(tileEntity);
 
         if (renderer == null) return;
-        if(tileEntity.getDistanceFrom(this.viewLerpPosX, this.viewLerpPosY, this.viewLerpPosZ) > 4096D * this.settings.entityRenderDistance.value) return;
+        if (tileEntity.getDistanceFrom(this.viewLerpPosX, this.viewLerpPosY, this.viewLerpPosZ) > 4096D * GameSettings.ENTITY_RENDER_DISTANCE.value)
+            return;
         if (!renderer.isVisible(tileEntity, camera, partialTick)) return;
 
         GLRenderer.setLightmapCoord1i(world.getLightmapCoord(tileEntity.x, tileEntity.y, tileEntity.z, 0));
         GLRenderer.setColor3f(1f, 1f, 1f);
         renderer.doRender(tessellator,
             tileEntity,
-            (double)tileEntity.x - renderPosX,
-            (double)tileEntity.y - renderPosY,
-            (double)tileEntity.z - renderPosZ, partialTick);
+            (double) tileEntity.x - renderPosX,
+            (double) tileEntity.y - renderPosY,
+            (double) tileEntity.z - renderPosZ, partialTick);
     }
 
-    public <T extends TileEntity> void renderTileEntity(final @NotNull TessellatorGeneral tessellator, final @NotNull T tileEntity, final double x, final double y, final double z, final float partialTick)
-    {
+    public <T extends TileEntity> void renderTileEntity(final @NotNull TessellatorGeneral tessellator, final @NotNull T tileEntity, final double x, final double y, final double z, final float partialTick) {
         final TileEntityRenderer<T> renderer = getRenderer(tileEntity);
-        if(renderer != null)
-        {
+        if (renderer != null) {
             renderer.doRender(tessellator, tileEntity, x, y, z, partialTick);
         }
     }
@@ -144,8 +130,7 @@ public final class TileEntityRenderDispatcher
         }
     }
 
-    public @NotNull FontRenderer getFont()
-    {
+    public @NotNull FontRenderer getFont() {
         return this.font;
     }
 
diff --git a/game/client/src/main/java/net/minecraft/client/render/WorldRenderer.java b/game/client/src/main/java/net/minecraft/client/render/WorldRenderer.java
index 4c36e0855..1c68fdc5e 100644
--- a/game/client/src/main/java/net/minecraft/client/render/WorldRenderer.java
+++ b/game/client/src/main/java/net/minecraft/client/render/WorldRenderer.java
@@ -1,9 +1,7 @@
 package net.minecraft.client.render;
 
-import java.util.List;
-import java.util.Random;
-
 import com.mojang.logging.LogUtils;
+import net.minecraft.client.option.enums.ParticlesQuality;
 import net.minecraft.client.render.culling.CameraFrustum;
 import net.minecraft.client.render.renderer.BlendFactor;
 import net.minecraft.client.render.renderer.CompareFunc;
@@ -27,14 +25,13 @@ import org.joml.primitives.AABBdc;
 import org.lwjgl.input.Mouse;
 
 import net.minecraft.client.Minecraft;
-import net.minecraft.client.render.particle.ParticleWaterDrop;
-import net.minecraft.client.render.particle.ParticleSmoke;
 import net.minecraft.client.entity.player.PlayerLocal;
 import net.minecraft.client.gui.ScreenPhotoMode;
 import net.minecraft.client.gui.modelviewer.ScreenModelViewer;
 import net.minecraft.client.input.InputType;
 import net.minecraft.client.input.MouseFilter;
 import net.minecraft.client.input.PlayerInput;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.camera.CameraUtil;
 import net.minecraft.client.render.camera.EntityCamera;
 import net.minecraft.client.render.camera.EntityCameraFirstPerson;
@@ -43,15 +40,17 @@ import net.minecraft.client.render.camera.EntityCameraSleeping;
 import net.minecraft.client.render.camera.EntityCameraThirdPersonFront;
 import net.minecraft.client.render.camera.EntityCameraThirdPersonRear;
 import net.minecraft.client.render.colorizer.Colorizers;
-import net.minecraft.client.render.texture.stitcher.TextureRegistry;
+import net.minecraft.client.render.particle.ParticleSmoke;
+import net.minecraft.client.render.particle.ParticleWaterDrop;
 import net.minecraft.client.render.tessellator.TessellatorGeneral;
-import net.minecraft.core.util.debug.Debug;
-import net.minecraft.core.util.phys.HitResult;
+import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.sound.SoundCategory;
+import net.minecraft.core.util.debug.Debug;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.util.helper.Time;
+import net.minecraft.core.util.phys.HitResult;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.chunk.provider.IChunkProvider;
@@ -59,6 +58,9 @@ import net.minecraft.core.world.weather.Weather;
 import org.lwjgl.opengl.GL41;
 import org.slf4j.Logger;
 
+import java.util.List;
+import java.util.Random;
+
 public class WorldRenderer {
     private static final Logger LOGGER = LogUtils.getLogger();
     public static final long nsPerSecond = 1_000_000_000L;
@@ -116,7 +118,7 @@ public class WorldRenderer {
 
     private void updateSpeedFov() {
         PlayerLocal player = this.mc.thePlayer;
-        float currentFovModifier = this.mc.gameSettings.fovModification.value ? player.getFovModifier() : 1f;
+        float currentFovModifier = GameSettings.FOV_MODIFICATION.value ? player.getFovModifier() : 1f;
         this.fovModOld = this.fovMod;
         this.fovMod += (currentFovModifier - this.fovMod) * 0.5f;
     }
@@ -208,7 +210,7 @@ public class WorldRenderer {
             fov = (int) (this.mc.activeCamera.getFov() * 100 + 30);
             fov *= org.joml.Math.lerp(this.fovModOld, this.fovMod, partialTick);
         }
-        if (this.mc.gameSettings.fovModification.value && CameraUtil.isUnderLiquid(this.mc.activeCamera, this.mc.currentWorld, Materials.WATER, partialTick)) {
+        if (GameSettings.FOV_MODIFICATION.value && CameraUtil.isUnderLiquid(this.mc.activeCamera, this.mc.currentWorld, Materials.WATER, partialTick)) {
             fov = fov - 10;
         }
         if (entityliving != null && entityliving.getHealth() <= 0) {
@@ -271,11 +273,11 @@ public class WorldRenderer {
                         this.mc.activeCamera.getX(partialTick), this.mc.activeCamera.getY(partialTick), this.mc.activeCamera.getZ(partialTick), this.mc.activeCamera.getYRot(partialTick), this.mc.activeCamera.getXRot(partialTick)
                     );
                 }
-            } else if (this.mc.gameSettings.thirdPersonView.value == 0 && !(this.mc.activeCamera instanceof EntityCameraFirstPerson)) {
+            } else if (GameSettings.THIRD_PERSON_VIEW.value == 0 && !(this.mc.activeCamera instanceof EntityCameraFirstPerson)) {
                 this.mc.activeCamera = new EntityCameraFirstPerson(this.mc, mob);
-            } else if (this.mc.gameSettings.thirdPersonView.value == 1 && !(this.mc.activeCamera instanceof EntityCameraThirdPersonRear)) {
+            } else if (GameSettings.THIRD_PERSON_VIEW.value == 1 && !(this.mc.activeCamera instanceof EntityCameraThirdPersonRear)) {
                 this.mc.activeCamera = new EntityCameraThirdPersonRear(this.mc, mob);
-            } else if (this.mc.gameSettings.thirdPersonView.value == 2 && !(this.mc.activeCamera instanceof EntityCameraThirdPersonFront)) {
+            } else if (GameSettings.THIRD_PERSON_VIEW.value == 2 && !(this.mc.activeCamera instanceof EntityCameraThirdPersonFront)) {
                 this.mc.activeCamera = new EntityCameraThirdPersonFront(this.mc, mob);
             }
         }
@@ -285,7 +287,7 @@ public class WorldRenderer {
     public @NotNull Matrix4f orientCamera(@NotNull Matrix4f matrix, float partialTick) {
         setupCamera(partialTick);
 
-        if (!(this.mc.currentScreen instanceof ScreenPhotoMode) && !this.mc.gameSettings.lockCamera.value) {
+        if (!(this.mc.currentScreen instanceof ScreenPhotoMode) && !GameSettings.LOCK_CAMERA.value) {
             matrix.rotateX(org.joml.Math.toRadians((float) this.mc.activeCamera.getXRot(partialTick)));
             matrix.rotateY(org.joml.Math.toRadians((float) (this.mc.activeCamera.getYRot(partialTick) + 180F)));
         }
@@ -299,7 +301,7 @@ public class WorldRenderer {
 
     public @NotNull Matrix4f getProjectionMatrix(@NotNull Matrix4f matrix, float partialTick) {
         matrix.identity();
-        this.farPlaneDistance = this.mc.gameSettings.renderDistance.value * 16;
+        this.farPlaneDistance = GameSettings.RENDER_DISTANCE.value * 16;
         float fov = getFOVModifier(partialTick, true);
         if (this.zooming) {
             fov = getZoomedFOV(fov, partialTick);
@@ -320,17 +322,18 @@ public class WorldRenderer {
     public @NotNull Matrix4f getViewMatrix(@NotNull Matrix4f matrix, float partialTick) {
         matrix.identity();
         hurtCameraEffect(matrix, partialTick);
-        if (this.mc.gameSettings.viewBobbing.value && !(this.mc.currentScreen instanceof ScreenPhotoMode)) {
+        if (GameSettings.VIEW_BOBBING.value && !(this.mc.currentScreen instanceof ScreenPhotoMode)) {
             setupViewBobbing(matrix, partialTick, false);
         }
 
-        final float portalIntensity = this.mc.gameSettings.screenMotionEffects.value ? MathHelper.lerp(this.mc.thePlayer.prevTimeInPortal, this.mc.thePlayer.timeInPortal, partialTick) : 0f;
+        final float portalIntensity = GameSettings.SCREEN_MOTION_EFFECTS.value ? MathHelper.lerp(this.mc.thePlayer.prevTimeInPortal, this.mc.thePlayer.timeInPortal, partialTick) : 0f;
         if (portalIntensity > 0.0F) {
             float f3 = 5F / (portalIntensity * portalIntensity + 5F) - portalIntensity * 0.04F;
             f3 *= f3;
-            matrix.rotate(org.joml.Math.toRadians(((float) this.rendererUpdateCount + partialTick) * 20F), 0.0F, 1.0F, 1.0F);
+            float rotation = org.joml.Math.toRadians(((float) this.rendererUpdateCount + partialTick) * 20F);
+            matrix.rotate(rotation, 0.0F, 0.7071f, 0.7071f);
             matrix.scale(1.0F / f3, 1.0F, 1.0F);
-            matrix.rotate(org.joml.Math.toRadians(-((float) this.rendererUpdateCount + partialTick) * 20F), 0.0F, 1.0F, 1.0F);
+            matrix.rotate(-rotation, 0.0F, 0.7071f, 0.7071f);
         }
 
         orientCamera(matrix, partialTick);
@@ -340,7 +343,7 @@ public class WorldRenderer {
     private void renderHand(float partialTick) {
         Matrix4f projMat = GLRenderer.projectionM4f();
         projMat.identity();
-        this.farPlaneDistance = this.mc.gameSettings.renderDistance.value * 16;
+        this.farPlaneDistance = GameSettings.RENDER_DISTANCE.value * 16;
         float fov = getFOVModifier(partialTick, false);
         if (this.zooming) {
             fov = getZoomedFOV(fov, partialTick);
@@ -360,10 +363,10 @@ public class WorldRenderer {
 
         GLRenderer.pushFrame();
         hurtCameraEffect(viewMat, partialTick);
-        if (this.mc.gameSettings.viewBobbing.value) {
+        if (GameSettings.VIEW_BOBBING.value) {
             setupViewBobbing(viewMat, partialTick, true);
         }
-        if (this.mc.gameSettings.thirdPersonView.value == 0 && !(this.mc.currentScreen instanceof ScreenPhotoMode) && !(!(this.mc.activeCamera instanceof EntityCamera) || ((EntityCamera) this.mc.activeCamera).mob.isPlayerSleeping()) && this.mc.gameSettings.immersiveMode.drawHand()) {
+        if (GameSettings.THIRD_PERSON_VIEW.value == 0 && !(this.mc.currentScreen instanceof ScreenPhotoMode) && !(!(this.mc.activeCamera instanceof EntityCamera) || ((EntityCamera) this.mc.activeCamera).mob.isPlayerSleeping()) && GameSettings.IMMERSIVE_MODE.drawHand()) {
             this.lightmapHelper.enableLightmapRendering();
             if (!this.zooming) this.itemRenderer.renderItemInFirstPerson(partialTick);
             this.lightmapHelper.disableLightmapRendering();
@@ -373,11 +376,11 @@ public class WorldRenderer {
         Debug.change("post");
         this.mc.renderer.endRenderWorld(partialTick);
 
-        if (this.mc.gameSettings.thirdPersonView.value == 0 && !(!(this.mc.activeCamera instanceof EntityCamera) || ((EntityCamera) this.mc.activeCamera).mob.isPlayerSleeping())) {
+        if (GameSettings.THIRD_PERSON_VIEW.value == 0 && !(!(this.mc.activeCamera instanceof EntityCamera) || ((EntityCamera) this.mc.activeCamera).mob.isPlayerSleeping())) {
             this.itemRenderer.renderOverlays(partialTick);
             hurtCameraEffect(viewMat, partialTick);
         }
-        if (this.mc.gameSettings.viewBobbing.value) {
+        if (GameSettings.VIEW_BOBBING.value) {
             setupViewBobbing(viewMat, partialTick, false);
         }
     }
@@ -408,7 +411,7 @@ public class WorldRenderer {
         this.lightmapHelper.update(partialTick);
         if (this.mc.inGameHasFocus) {
             if (Mouse.isGrabbed()) {
-                float sensitivity = this.mc.gameSettings.mouseSensitivity.value * 0.6F + 0.2F;
+                float sensitivity = GameSettings.MOUSE_SENSITIVITY.value * 0.6F + 0.2F;
                 sensitivity = sensitivity * sensitivity * sensitivity * 8.0f;
                 if (this.zooming) sensitivity *= 0.25f;
 
@@ -418,10 +421,10 @@ public class WorldRenderer {
 //                System.out.printf("%s %s\n", deltaX, deltaY);
 
                 int l = 1;
-                if (this.mc.gameSettings.invertMouse.value) {
+                if (GameSettings.INVERT_MOUSE.value) {
                     l = -1;
                 }
-                if (this.mc.gameSettings.smoothCamera.value) {
+                if (GameSettings.SMOOTH_CAMERA.value) {
                     deltaX = this.mouseFilterXAxis.getSmoothedDelta(deltaX, 0.05F * sensitivity);
                     deltaY = this.mouseFilterYAxis.getSmoothedDelta(deltaY, 0.05F * sensitivity);
                 } else {
@@ -431,7 +434,7 @@ public class WorldRenderer {
                 this.mc.thePlayer.interpolateTurn(deltaX, deltaY * (float) l);
             }
             if (this.mc.controllerInput != null) {
-                double speed = Time.delta * 2000 * (this.mc.gameSettings.controllerSensitivity.value + 0.5f);
+                double speed = Time.delta * 2000 * (GameSettings.CONTROLLER_SENSITIVITY.value + 0.5f);
                 if (this.zooming) speed *= 0.25f;
 
                 double x = this.mc.controllerInput.joyRight.getX() * speed;
@@ -439,7 +442,7 @@ public class WorldRenderer {
 
                 this.mc.thePlayer.interpolateTurn((float) x, (float) y);
             }
-            if (!this.mc.gameSettings.showFrameTimes.value) {
+            if (!GameSettings.SHOW_FRAME_TIMES.value) {
                 // Arrow key turning
                 // !!!!! Needs to happen somewhere that isnt updated only 20 times per second
                 PlayerInput playerInput = this.mc.thePlayer.input;
@@ -447,10 +450,10 @@ public class WorldRenderer {
                 float x = 0.0f;
                 float y = 0.0f;
 
-                playerInput.pressedLookUp = this.mc.gameSettings.keyLookUp.isPressed();
-                playerInput.pressedLookDown = this.mc.gameSettings.keyLookDown.isPressed();
-                playerInput.pressedLookLeft = this.mc.gameSettings.keyLookLeft.isPressed();
-                playerInput.pressedLookRight = this.mc.gameSettings.keyLookRight.isPressed();
+                playerInput.pressedLookUp = GameSettings.KEY_LOOK_UP.isPressed();
+                playerInput.pressedLookDown = GameSettings.KEY_LOOK_DOWN.isPressed();
+                playerInput.pressedLookLeft = GameSettings.KEY_LOOK_LEFT.isPressed();
+                playerInput.pressedLookRight = GameSettings.KEY_LOOK_RIGHT.isPressed();
 
                 if (playerInput.pressedLookUp) y++;
                 if (playerInput.pressedLookDown) y--;
@@ -458,7 +461,7 @@ public class WorldRenderer {
                 if (playerInput.pressedLookLeft) x--;
                 if (playerInput.pressedLookRight) x++;
 
-                float sensitivity = (float) (Time.delta * 1000 * (this.mc.gameSettings.mouseSensitivity.value + 0.5f));
+                float sensitivity = (float) (Time.delta * 1000 * (GameSettings.MOUSE_SENSITIVITY.value + 0.5f));
                 if (this.mc.thePlayer.isSneaking()) sensitivity *= 0.5f;
                 if (this.zooming) sensitivity *= 0.25f;
 
@@ -476,25 +479,25 @@ public class WorldRenderer {
         int mouseX = (Mouse.getX() * width) / this.mc.resolution.getWidthScreenCoords();
         int mouseY = height - (Mouse.getY() * height) / this.mc.resolution.getHeightScreenCoords() - 1;
         int c = 200;
-        if (this.mc.gameSettings.enableVsync.value) // VSync
+        if (GameSettings.ENABLE_VSYNC.value) // VSync
         {
 //        	c = mc.gameWindow.getFrequency(); // Cap fps when minimized
             c = 999;
         } else {
-            c = this.mc.gameSettings.customFpsLimit.value;
+            c = GameSettings.CUSTOM_FPS_LIMIT.value;
         }
         if (c <= 0) c = 1;
         GL41.glViewport(0, 0, this.mc.gameWindow.getWidthPixels(), this.mc.gameWindow.getHeightPixels());
         if (this.mc.currentWorld != null) {
             Debug.change("world");
-            if (!this.mc.gameSettings.enableVsync.value && this.mc.gameSettings.customFpsLimit.value == 0) // Max FPS
+            if (!GameSettings.ENABLE_VSYNC.value && GameSettings.CUSTOM_FPS_LIMIT.value == 0) // Max FPS
             {
                 renderWorld(partialTick, 0);
             } else {
                 renderWorld(partialTick, this.systemTime + (nsPerSecond / c));
             }
             Debug.change("misc");
-            if (this.mc.gameSettings.enableVsync.value || this.mc.gameSettings.customFpsLimit.value > 0) // Power saver
+            if (GameSettings.ENABLE_VSYNC.value || GameSettings.CUSTOM_FPS_LIMIT.value > 0) // Power saver
             {
                 Debug.change("sleep");
                 long timeToSleep = ((this.systemTime + (nsPerSecond / c)) - System.nanoTime());
@@ -519,7 +522,7 @@ public class WorldRenderer {
             GLRenderer.viewM4f().identity();
             GLRenderer.modelM4f().identity();
             setupScaledResolution();
-            if (this.mc.gameSettings.enableVsync.value || this.mc.gameSettings.customFpsLimit.value > 0) {
+            if (GameSettings.ENABLE_VSYNC.value || GameSettings.CUSTOM_FPS_LIMIT.value > 0) {
                 Debug.change("sleep");
                 long l2 = ((this.systemTime + (1_000_000_000L / c)) - System.nanoTime()) / 1_000_000L;
                 if (l2 < 0L) {
@@ -558,7 +561,7 @@ public class WorldRenderer {
 
             if (this.mc.currentScreen != null) {
                 CursorShape newCursor = this.mc.currentScreen.getDesiredCursor();
-                if (!this.mc.gameSettings.dynamicCursor.value) {
+                if (!GameSettings.DYNAMIC_CURSOR.value) {
                     newCursor = CursorShape.ARROW;
                 }
                 if (this.mc.gameWindow.getCursorShape() != newCursor) {
@@ -609,7 +612,7 @@ public class WorldRenderer {
         getViewMatrix(GLRenderer.viewM4f(), pt);
         CameraFrustum.recalcFrustrum();
         Debug.change("sky");
-        if ((this.mc.gameSettings.renderDistance.value > 4) && !(this.mc.currentScreen instanceof ScreenModelViewer)) {
+        if ((GameSettings.RENDER_DISTANCE.value > 4) && !(this.mc.currentScreen instanceof ScreenModelViewer)) {
             renderGlobal.renderSky(partialTicks);
         }
 
@@ -619,13 +622,13 @@ public class WorldRenderer {
         this.mc.renderGlobal.cull(this.mc.activeCamera.getFrustum(), partialTicks);
 
         Debug.change("aurora");
-        if (this.mc.gameSettings.aurora.value && WorldTypeFXDispatcher.getInstance().getDispatch(this.mc.currentWorld.getWorldType()).hasAurora()) {
+        if (GameSettings.AURORA.value && WorldTypeFXDispatcher.getInstance().getDispatch(this.mc.currentWorld.getWorldType()).hasAurora()) {
             renderGlobal.renderAurora(this.mc.activeCamera, partialTicks);
         }
         Debug.change("update");
 
         int loops = 1;
-        if (this.mc.gameSettings.keyLoadChunksQuickly.isPressed()) {
+        if (GameSettings.KEY_LOAD_CHUNKS_QUICKLY.isPressed()) {
             loops = 40;
         }
         for (int i = 0; i < loops; i++) {
@@ -682,10 +685,10 @@ public class WorldRenderer {
         }
 
         Debug.change("debugoverlays");
-        if (this.mc.gameSettings.showCollisionBoxes.value) {
+        if (GameSettings.SHOW_COLLISION_BOXES.value) {
             renderGlobal.drawDebugEntityOutlines(this.mc.activeCamera, partialTicks);
         }
-        if (this.mc.gameSettings.showChunkBorders.value) {
+        if (GameSettings.SHOW_CHUNK_BORDERS.value) {
             renderGlobal.drawDebugChunkBorders(this.mc.activeCamera, partialTicks);
         }
         GLRenderer.setBlendFunc(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA);
@@ -711,7 +714,7 @@ public class WorldRenderer {
         GLRenderer.enableState(State.CULL_FACE);
         GLRenderer.disableState(State.BLEND);
         renderRainSnow(partialTicks);
-        if (this.mc.gameSettings.clouds.value) {
+        if (GameSettings.CLOUDS.value) {
             Debug.change("clouds");
             this.fogManager.setupFog(FogManager.FOG_MODE_SKY, this.farPlaneDistance, partialTicks, GLRenderer.getFogState());
             renderGlobal.renderClouds(partialTicks);
@@ -726,12 +729,13 @@ public class WorldRenderer {
     }
 
     private void addRainParticles() {
+        if (GameSettings.PARTICLES_QUALITY.value == ParticlesQuality.NONE) return;
         Weather weather = this.mc.currentWorld.getCurrentWeather();
         if (!(weather instanceof IPrecipitation precipitation) || !precipitation.spawnRainParticles()) return;
 
         float f = this.mc.currentWorld.weatherManager.getWeatherIntensity() * this.mc.currentWorld.weatherManager.getWeatherPower();
 
-        if (this.mc.gameSettings.fancyGraphics.value != 1) {
+        if (GameSettings.PARTICLES_QUALITY.value == ParticlesQuality.REDUCED) {
             f /= 2.0F;
         }
         if (f == 0.0F) {
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/color/BlockColorWater.java b/game/client/src/main/java/net/minecraft/client/render/block/color/BlockColorWater.java
index ec3ceaed2..350195a42 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/color/BlockColorWater.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/color/BlockColorWater.java
@@ -1,6 +1,7 @@
 package net.minecraft.client.render.block.color;
 
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.colorizer.Colorizer;
 import net.minecraft.core.world.WorldSource;
 import net.minecraft.core.world.pos.TilePosc;
@@ -16,7 +17,7 @@ public class BlockColorWater extends BlockColorCustom {
 	
 	@Override
 	public int getFallbackColor(int meta, int tintIndex) {
-		if(!this.mc.gameSettings.biomeWater.value || (this.mc.currentWorld != null && this.mc.currentWorld.isRetro())) {
+		if(!GameSettings.BIOME_WATER.value || (this.mc.currentWorld != null && this.mc.currentWorld.isRetro())) {
 			return 0xFFFFFFFF;
 		}
 		return super.getFallbackColor(meta, tintIndex);
@@ -24,7 +25,7 @@ public class BlockColorWater extends BlockColorCustom {
 	
 	@Override
 	public int getWorldColor(@NotNull WorldSource source, @NotNull TilePosc tilePos, int tintIndex) {
-		if(!this.mc.gameSettings.biomeWater.value || source.isRetro()) {
+		if(!GameSettings.BIOME_WATER.value || source.isRetro()) {
 			return 0xFFFFFFFF;
 		}
 		return super.getWorldColor(source, tilePos, tintIndex);
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 7dc2e7fcf..7684fd75a 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
@@ -568,10 +568,10 @@ public final class BlockModelDispatcher
         addDispatch(new BlockModelGenericLantern<>(Blocks.LANTERN_FIREFLY_RED, loadDataModel("minecraft:block/lantern_firefly/red"), loadDataModel("minecraft:block/lantern_firefly/red_hanging")));
         addDispatch(new BlockModelGenericJar<>(Blocks.JAR_GLASS));
 
-        addDispatch(new BlockModelGenericLantern<>(Blocks.JAR_BUTTERFLY_BLUE, loadDataModel("minecraft:block/jar_butterfly"), loadDataModel("minecraft:block/jar_butterfly")));
-        addDispatch(new BlockModelGenericLantern<>(Blocks.JAR_BUTTERFLY_ORANGE, loadDataModel("minecraft:block/jar_butterfly"), loadDataModel("minecraft:block/jar_butterfly")));
-        addDispatch(new BlockModelGenericLantern<>(Blocks.JAR_BUTTERFLY_PINK, loadDataModel("minecraft:block/jar_butterfly"), loadDataModel("minecraft:block/jar_butterfly")));
-        addDispatch(new BlockModelGenericLantern<>(Blocks.JAR_BUTTERFLY_SILVER, loadDataModel("minecraft:block/jar_butterfly"), loadDataModel("minecraft:block/jar_butterfly")));
+        addDispatch(new BlockModelGenericLantern<>(Blocks.JAR_BUTTERFLY_BLUE, loadDataModel("minecraft:block/jar_butterfly"), loadDataModel("minecraft:block/jar_butterfly_hanging")));
+        addDispatch(new BlockModelGenericLantern<>(Blocks.JAR_BUTTERFLY_ORANGE, loadDataModel("minecraft:block/jar_butterfly"), loadDataModel("minecraft:block/jar_butterfly_hanging")));
+        addDispatch(new BlockModelGenericLantern<>(Blocks.JAR_BUTTERFLY_PINK, loadDataModel("minecraft:block/jar_butterfly"), loadDataModel("minecraft:block/jar_butterfly_hanging")));
+        addDispatch(new BlockModelGenericLantern<>(Blocks.JAR_BUTTERFLY_SILVER, loadDataModel("minecraft:block/jar_butterfly"), loadDataModel("minecraft:block/jar_butterfly_hanging")));
         addDispatch(new BlockModelGenericPebbles<>(Blocks.OVERLAY_PEBBLES));
 
         addDispatch(new BlockModelGenericFenceThin<>(Blocks.FENCE_CHAINLINK, "minecraft:block/fence_thin/chain"));
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFluid.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFluid.java
index f7a21a501..d1c569f3d 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFluid.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelFluid.java
@@ -53,10 +53,10 @@ public class BlockModelFluid<T extends BlockLogicFluid> extends BlockModelStanda
         float he = this.block.getLogic().getFluidHeight(worldSource, tilePos.add(1, 0, 0, queryPos));
         if (renderBlocks.renderAllFaces || renderTop) {
             didRender = true;
-            IconCoordinate texture = getBlockTextureFromSideAndMetadata(Side.TOP, meta);
+            IconCoordinate tex = getBlockTextureFromSideAndMetadata(Side.TOP, meta);
             float rotation = (float) this.block.getLogic().getSlopeAngle(worldSource, tilePos);
             if (rotation > -999F) {
-                texture = getBlockTextureFromSideAndMetadata(Side.NORTH, meta);
+                tex = getBlockTextureFromSideAndMetadata(Side.NORTH, meta);
             } else {
                 rotation = 0.0F;
             }
@@ -64,39 +64,33 @@ public class BlockModelFluid<T extends BlockLogicFluid> extends BlockModelStanda
             int lightUp = this.block.getLightmapCoord(worldSource, tilePos.up(queryPos));
 
             tessellator.setLightmapCoord1i(LightmapHelper.max(light, lightUp));
-            if (texture.namespaceId.toString().contains("_flowing")) {
-                double centerU = texture.getSubIconU(0.5);
-                double centerV = texture.getSubIconV(0.5);
-                float cSin = Math.cos(rotation) / 2;
-                float sin = Math.sin(rotation) / 2;
-
-                double minU = texture.getIconUMin();
-                double maxU = texture.getIconUMax();
-                double minV = texture.getIconVMin();
-                double maxV = texture.getIconVMax();
-
-                double du = (maxU - centerU);
-                double dv = (maxV - centerV);
+            if (tex.namespaceId.toString().contains("_flowing")) {
+                float cos = Math.cos(-rotation + Math.PI_OVER_2_f);
+                float sin = Math.sin(-rotation + Math.PI_OVER_2_f);
 
                 tessellator.setNormal(0, 1, 0);
                 tessellator.addVertexWithUV(x, (float) y + h, z,
-                    Math.clamp(minU, maxU, -du * sin - dv * cSin + centerU),
-                    Math.clamp(minV, maxV, dv * sin + -du * cSin + centerV));
+                    tex.getSubIconU(((-0.25) * cos - (-0.25) * sin) + 0.5),
+                    tex.getSubIconV(((-0.25) * sin + (-0.25) * cos) + 0.5)
+                );
                 tessellator.addVertexWithUV(x, (float) y + hs, z + 1,
-                    Math.clamp(minU, maxU, du * sin - dv * cSin + centerU),
-                    Math.clamp(minV, maxV, dv * sin + du * cSin + centerV));
+                    tex.getSubIconU(((-0.25) * cos - (0.25) * sin) + 0.5),
+                    tex.getSubIconV(((-0.25) * sin + (0.25) * cos) + 0.5)
+                );
                 tessellator.addVertexWithUV(x + 1, (float) y + hes, z + 1,
-                    Math.clamp(minU, maxU, du * sin - (-dv) * cSin + centerU),
-                    Math.clamp(minV, maxV, -dv * sin + du * cSin + centerV));
+                    tex.getSubIconU(((0.25) * cos - (0.25) * sin) + 0.5),
+                    tex.getSubIconV(((0.25) * sin + (0.25) * cos) + 0.5)
+                );
                 tessellator.addVertexWithUV(x + 1, (float) y + he, z,
-                    Math.clamp(minU, maxU, -du * sin - (-dv) * cSin + centerU),
-                    Math.clamp(minV, maxV, -dv * sin + -du * cSin + centerV));
+                    tex.getSubIconU(((0.25) * cos - (-0.25) * sin) + 0.5),
+                    tex.getSubIconV(((0.25) * sin + (-0.25) * cos) + 0.5)
+                );
             } else {
                 tessellator.setNormal(0, 1, 0);
-                tessellator.addVertexWithUV(x, (float) y + h, z, texture.getIconUMin(), texture.getIconVMax());
-                tessellator.addVertexWithUV(x, (float) y + hs, z + 1, texture.getIconUMax(), texture.getIconVMax());
-                tessellator.addVertexWithUV(x + 1, (float) y + hes, z + 1, texture.getIconUMax(), texture.getIconVMin());
-                tessellator.addVertexWithUV(x + 1, (float) y + he, z, texture.getIconUMin(), texture.getIconVMin());
+                tessellator.addVertexWithUV(x, (float) y + h, z, tex.getIconUMin(), tex.getIconVMax());
+                tessellator.addVertexWithUV(x, (float) y + hs, z + 1, tex.getIconUMax(), tex.getIconVMax());
+                tessellator.addVertexWithUV(x + 1, (float) y + hes, z + 1, tex.getIconUMax(), tex.getIconVMin());
+                tessellator.addVertexWithUV(x + 1, (float) y + he, z, tex.getIconUMin(), tex.getIconVMin());
             }
 
         }
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelGlass.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelGlass.java
index 7fd6d8f60..1c8e56aa8 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelGlass.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelGlass.java
@@ -1,6 +1,6 @@
 package net.minecraft.client.render.block.model;
 
-import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.core.block.Block;
@@ -49,7 +49,7 @@ public class BlockModelGlass<T extends BlockLogic> extends BlockModelTransparent
 
     @Override
     public @Nullable IconCoordinate getBlockTexture(final @NotNull WorldSource source, final @NotNull TilePosc tilePos, final @NotNull Side side) {
-        if (Minecraft.getMinecraft().gameSettings.connectedGlass.value) {
+        if (GameSettings.CONNECTED_GLASS.value) {
             final boolean u;
             final boolean d;
             final boolean l;
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLeaves.java b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLeaves.java
index d76558d41..9ddaa60b5 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLeaves.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/BlockModelLeaves.java
@@ -1,6 +1,7 @@
 package net.minecraft.client.render.block.model;
 
-import net.minecraft.client.render.block.model.generic.BlockModelGenericLeaves;
+import net.minecraft.client.option.GameSettings;
+import net.minecraft.client.option.enums.LeavesQuality;
 import net.minecraft.client.render.tessellator.TessellatorGeneral;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
@@ -50,14 +51,14 @@ public class BlockModelLeaves<T extends BlockLogic> extends BlockModelStandard<T
     @Override
     public @Nullable IconCoordinate getBlockTextureFromSideAndMetadata(@NotNull Side side, int data) {
         if (this.canBeRetro && isRetro()) {
-            return BlockModelGenericLeaves.fancyGraphics ? this.retroLeavesFancy : this.retroLeaves;
+            return GameSettings.LEAVES_QUALITY.value != LeavesQuality.FAST ? this.retroLeavesFancy : this.retroLeaves;
         }
-        return BlockModelGenericLeaves.fancyGraphics ? this.fancyLeavesTexture : super.getBlockTextureFromSideAndMetadata(side, data);
+        return GameSettings.LEAVES_QUALITY.value != LeavesQuality.FAST ? this.fancyLeavesTexture : super.getBlockTextureFromSideAndMetadata(side, data);
     }
 
     @Override
     public boolean shouldSideBeRendered(@NotNull WorldSource source, @NotNull AABBdc bounds, @NotNull TilePosc tilePos, @NotNull Side side) {
-        if (!BlockModelGenericLeaves.fancyGraphics && source.getBlockType(tilePos) == this.block) {
+        if (GameSettings.LEAVES_QUALITY.value == LeavesQuality.FANCY && source.getBlockType(tilePos) == this.block) {
             return false;
         } else {
             return super.shouldSideBeRendered(source, bounds, tilePos, side);
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLeaves.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLeaves.java
index 63b4982dd..9e50ab7c1 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLeaves.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericLeaves.java
@@ -1,5 +1,7 @@
 package net.minecraft.client.render.block.model.generic;
 
+import net.minecraft.client.option.GameSettings;
+import net.minecraft.client.option.enums.LeavesQuality;
 import net.minecraft.client.render.block.model.BlockModelDispatcher;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.BlockLogic;
@@ -12,25 +14,34 @@ import org.jetbrains.annotations.Nullable;
 import org.useless.dragonfly.models.block.StaticBlockModel;
 
 public class BlockModelGenericLeaves<T extends BlockLogic> extends BlockModelGeneric<T> {
-    public static boolean fancyGraphics;
     public @NotNull StaticBlockModel fast;
+    public @NotNull StaticBlockModel smart;
     public BlockModelGenericLeaves(@NotNull Block<T> block, @NotNull String key) {
         super(block, BlockModelDispatcher.loadDataModel(key + "_fancy"));
         this.fast = BlockModelDispatcher.loadDataModel(key + "_fast").asModel();
+        this.smart = BlockModelDispatcher.loadDataModel(key + "_smart").asModel();
     }
 
-    public static void setGraphicsLevel(boolean graphicsLevel) {
-        fancyGraphics = graphicsLevel;
+    @Override
+    public @NotNull StaticBlockModel getModelFromData(int data) {
+        return switch (GameSettings.LEAVES_QUALITY.value) {
+            case FANCY, SMART -> this.staticModel;
+            case FAST -> this.fast;
+        };
     }
 
     @Override
-    public @NotNull StaticBlockModel getModelFromData(int data) {
-        return fancyGraphics ? super.getModelFromData(data) : this.fast;
+    public @NotNull StaticBlockModel getModel(@NotNull WorldSource source, @NotNull TilePosc tilePosc) {
+        return switch (GameSettings.LEAVES_QUALITY.value) {
+            case FANCY -> this.staticModel;
+            case SMART -> this.smart;
+            case FAST -> this.fast;
+        };
     }
 
     @Override
     public boolean cullSide(@NotNull WorldSource worldSource, @NotNull TilePosc blockPos, @Nullable Direction direction) {
-        if (fancyGraphics) {
+        if (GameSettings.LEAVES_QUALITY.value == LeavesQuality.FANCY) {
             return super.cullSide(worldSource, blockPos, direction);
         }
         if (direction != null) {
diff --git a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericSpikes.java b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericSpikes.java
index 4c1b2bbf0..43ec5f471 100644
--- a/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericSpikes.java
+++ b/game/client/src/main/java/net/minecraft/client/render/block/model/generic/BlockModelGenericSpikes.java
@@ -21,9 +21,34 @@ public class BlockModelGenericSpikes<T extends BlockLogic> extends BlockModelGen
 
     @Override
     public boolean renderAttached(@NotNull TessellatorGeneral tessellator, @NotNull WorldSource worldSource, @NotNull TilePosc tilePos, boolean cullFaces, @Nullable IconCoordinate overrideTexture) {
-        boolean didRender = super.renderAttached(tessellator, worldSource, tilePos, cullFaces, overrideTexture);
-        if (BlockLogicSpikes.isSpikesUp(worldSource.getBlockData(tilePos))) {
-            didRender |= this.spikes.renderAttached(this, tessellator, worldSource, tilePos, 0, 0, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+        int rotX = 1;
+        int rotY = 0;
+
+        int data = worldSource.getBlockData(tilePos);
+        switch (BlockLogicSpikes.getDirectionFromData(data)) {
+            case UP -> {
+                rotX = 2;
+            }
+            case DOWN -> {
+                rotX = 0;
+            }
+            case NORTH -> {
+                rotY = 0;
+            }
+            case SOUTH -> {
+                rotY = 2;
+            }
+            case WEST -> {
+                rotY = 1;
+            }
+            case EAST -> {
+                rotY = 3;
+            }
+        }
+
+        boolean didRender = getModel(worldSource, tilePos).renderAttached(this, tessellator, worldSource, tilePos, rotX, rotY, 0, 0, 0, 0, false, cullFaces, overrideTexture);
+        if (BlockLogicSpikes.isSpikesUp(data)) {
+            didRender |= this.spikes.renderAttached(this, tessellator, worldSource, tilePos, rotX, rotY, 0, 0, 0, 0, false, cullFaces, overrideTexture);
         }
         return didRender;
     }
diff --git a/game/client/src/main/java/net/minecraft/client/render/camera/EntityCamera.java b/game/client/src/main/java/net/minecraft/client/render/camera/EntityCamera.java
index 0e7bc9ce7..e993fc950 100644
--- a/game/client/src/main/java/net/minecraft/client/render/camera/EntityCamera.java
+++ b/game/client/src/main/java/net/minecraft/client/render/camera/EntityCamera.java
@@ -1,6 +1,7 @@
 package net.minecraft.client.render.camera;
 
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.culling.CameraFrustum;
 import net.minecraft.core.entity.Mob;
 import net.minecraft.core.util.helper.MathHelper;
@@ -86,7 +87,7 @@ public abstract class EntityCamera
 
     @Override
     public double getFov() {
-        return this.mc.gameSettings.FoV.get();
+        return GameSettings.FOV.get();
     }
 
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/render/culling/CameraFrustum.java b/game/client/src/main/java/net/minecraft/client/render/culling/CameraFrustum.java
index f7d88dc6a..ee5c2aeff 100644
--- a/game/client/src/main/java/net/minecraft/client/render/culling/CameraFrustum.java
+++ b/game/client/src/main/java/net/minecraft/client/render/culling/CameraFrustum.java
@@ -1,5 +1,6 @@
 package net.minecraft.client.render.culling;
 
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.camera.ICamera;
 import net.minecraft.client.render.renderer.GLRenderer;
 import org.jetbrains.annotations.NotNull;
@@ -13,7 +14,9 @@ public class CameraFrustum {
     private static final @NotNull Matrix4f matrix4f = new Matrix4f();
 
     public static void recalcFrustrum() {
-        frustum.set(GLRenderer.projectionM4f().mul(GLRenderer.viewM4f(), matrix4f).mul(GLRenderer.modelM4f(), matrix4f));
+        if (GameSettings.FRUSTUM_CULLING.value){
+            frustum.set(GLRenderer.projectionM4f().mul(GLRenderer.viewM4f(), matrix4f).mul(GLRenderer.modelM4f(), matrix4f));
+        }
     }
 
     public static @NotNull FrustumIntersection getFrustum() {
@@ -36,6 +39,10 @@ public class CameraFrustum {
     }
 
     public boolean isVisible(@NotNull AABBdc aabb, float partialTick) {
-        return cubeInFrustum(aabb, partialTick);
+        if (GameSettings.FRUSTUM_CULLING.value) {
+            return cubeInFrustum(aabb, partialTick);
+        } else {
+            return true;
+        }
     }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTexture.java b/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTexture.java
index 71e8c9787..b1c3318b5 100644
--- a/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTexture.java
+++ b/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTexture.java
@@ -1,12 +1,11 @@
 package net.minecraft.client.render.dynamictexture;
 
-import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
+import net.minecraft.client.option.enums.TextureAnimation;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import org.jetbrains.annotations.NotNull;
 
 public abstract class DynamicTexture {
-
-	public Minecraft mc = Minecraft.getMinecraft();
 	@NotNull
 	public final IconCoordinate targetTexture;
 	public byte[] imageData;
@@ -20,11 +19,11 @@ public abstract class DynamicTexture {
 	public abstract void update();
 
 	public boolean runUpdates(boolean isPaused) {
-		return mc.gameSettings.animations.value != 0 && !isPaused;
+		return GameSettings.TEXTURE_ANIMATIONS.value != TextureAnimation.OFF && !isPaused;
 	}
 	
 	public void initTexture() {
-		this.imageData = new byte[targetTexture.width * targetTexture.height * 4];
+		this.imageData = new byte[this.targetTexture.width * this.targetTexture.height * 4];
 	}
 	
 	public static int pmod(int a, int b) {
@@ -38,7 +37,7 @@ public abstract class DynamicTexture {
 		int b = (color >>  0) & 0xFF;
 		int a = (color >> 24) & 0xFF;
 		
-		array[i * 4 + 0] = (byte) r;
+		array[i * 4] = (byte) r;
 		array[i * 4 + 1] = (byte) g;
 		array[i * 4 + 2] = (byte) b;
 		array[i * 4 + 3] = (byte) a;
diff --git a/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCustom.java b/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCustom.java
index 1d9739ffa..05689987b 100644
--- a/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCustom.java
+++ b/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureCustom.java
@@ -4,6 +4,8 @@ import java.awt.image.BufferedImage;
 import java.util.Random;
 
 import com.mojang.logging.LogUtils;
+import net.minecraft.client.option.GameSettings;
+import net.minecraft.client.option.enums.TextureAnimation;
 import net.minecraft.client.render.texture.meta.AnimationProperties;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import net.minecraft.client.render.texturepack.TexturePackException;
@@ -184,6 +186,6 @@ public class DynamicTextureCustom extends DynamicTexture {
 	}
 	@Override
 	public boolean runUpdates(boolean isPaused) {
-		return this.mc.gameSettings.animations.value != 0 && (!isPaused || this.tickWhenPaused);
+		return GameSettings.TEXTURE_ANIMATIONS.value != TextureAnimation.OFF && (!isPaused || this.tickWhenPaused);
 	}
 }
diff --git a/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureFireflyJar.java b/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureFireflyJar.java
index 2e8a478b2..0b13882df 100644
--- a/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureFireflyJar.java
+++ b/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureFireflyJar.java
@@ -14,11 +14,11 @@ public class DynamicTextureFireflyJar extends DynamicTexture {
         super(texture);
 
         this.originalData = new byte[texture.getArea() * 4];
-        int[] data = texture.parentAtlas.getIconData("color", texture, new int[texture.getArea()]);
+        BufferedImage image = texture.parentAtlas.getImage("color", texture);
 
 		for(int x = 0; x < texture.width; x++) {
 			for(int y = 0; y < texture.height; y++) {
-				putPixel(this.originalData, y * texture.width + x, data[y * texture.width + x]);
+				putPixel(this.originalData, y * texture.width + x, image.getRGB(x, y));
 			}
 		}
 	}
diff --git a/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterFlow.java b/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterFlow.java
index 1d9bdfe47..94af132cc 100644
--- a/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterFlow.java
+++ b/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterFlow.java
@@ -1,6 +1,7 @@
 package net.minecraft.client.render.dynamictexture;
 
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 import org.jetbrains.annotations.NotNull;
 
@@ -21,11 +22,11 @@ public class DynamicTextureWaterFlow extends DynamicTexture {
 	@Override
 	public void postInit() {
 		initTexture();
-		
-		arr1 = new float[targetTexture.getArea()];
-		arr2 = new float[targetTexture.getArea()];
-		arr3 = new float[targetTexture.getArea()];
-		arr4 = new float[targetTexture.getArea()];
+
+        this.arr1 = new float[this.targetTexture.getArea()];
+        this.arr2 = new float[this.targetTexture.getArea()];
+        this.arr3 = new float[this.targetTexture.getArea()];
+        this.arr4 = new float[this.targetTexture.getArea()];
 	}
 
 	@Override
@@ -33,30 +34,30 @@ public class DynamicTextureWaterFlow extends DynamicTexture {
 		this.ticks++;
 
 		float bright;
-		for (int x = 0; x < targetTexture.width; ++x) {
-			for (int y = 0; y < targetTexture.height; ++y) {
+		for (int x = 0; x < this.targetTexture.width; ++x) {
+			for (int y = 0; y < this.targetTexture.height; ++y) {
 				bright = 0.0F;
 
 				for (int k = y - 2; k <= y; ++k) {
-					int r = pmod(x, targetTexture.width);
-					int g = pmod(k, targetTexture.height);
-					bright += this.arr1[r + g * targetTexture.width];
+					int r = pmod(x, this.targetTexture.width);
+					int g = pmod(k, this.targetTexture.height);
+					bright += this.arr1[r + g * this.targetTexture.width];
 				}
 
-				this.arr2[x + y * targetTexture.width] = bright / 3.2F + this.arr3[x + y * targetTexture.width] * 0.8F;
+				this.arr2[x + y * this.targetTexture.width] = bright / 3.2F + this.arr3[x + y * this.targetTexture.width] * 0.8F;
 			}
 		}
 
-		for (int x = 0; x < targetTexture.width; ++x) {
-			for (int y = 0; y < targetTexture.height; ++y) {
-				this.arr3[x + y * targetTexture.width] += this.arr4[x + y * targetTexture.width] * 0.05F;
-				if (this.arr3[x + y * targetTexture.width] < 0.0F) {
-					this.arr3[x + y * targetTexture.width] = 0.0F;
+		for (int x = 0; x < this.targetTexture.width; ++x) {
+			for (int y = 0; y < this.targetTexture.height; ++y) {
+				this.arr3[x + y * this.targetTexture.width] += this.arr4[x + y * this.targetTexture.width] * 0.05F;
+				if (this.arr3[x + y * this.targetTexture.width] < 0.0F) {
+					this.arr3[x + y * this.targetTexture.width] = 0.0F;
 				}
 
-				this.arr4[x + y * targetTexture.width] -= 0.3F;
+				this.arr4[x + y * this.targetTexture.width] -= 0.3F;
 				if (Math.random() < 0.2D) {
-					this.arr4[x + y * targetTexture.width] = 0.5F;
+					this.arr4[x + y * this.targetTexture.width] = 0.5F;
 				}
 			}
 		}
@@ -65,8 +66,8 @@ public class DynamicTextureWaterFlow extends DynamicTexture {
 		this.arr2 = this.arr1;
 		this.arr1 = var12;
 
-		for (int i = 0; i < targetTexture.getArea(); ++i) {
-			bright = this.arr1[pmod(i - this.ticks * targetTexture.width, targetTexture.getArea())];
+		for (int i = 0; i < this.targetTexture.getArea(); ++i) {
+			bright = this.arr1[pmod(i - this.ticks * this.targetTexture.width, this.targetTexture.getArea())];
 			if (bright > 1.0F) {
 				bright = 1.0F;
 			}
@@ -81,11 +82,11 @@ public class DynamicTextureWaterFlow extends DynamicTexture {
 			int b = 255;
 			int a = (int) (146.0F + var13 * 50.0F);
 
-			if (mc.gameSettings.biomeWater.value && !(mc.currentWorld != null && mc.currentWorld.isRetro())) {
+			if (GameSettings.BIOME_WATER.value && !(this.mc.currentWorld != null && this.mc.currentWorld.isRetro())) {
 				r = g = b = (r + g + b) / 3;
 			}
 
-			this.imageData[i * 4 + 0] = (byte) r;
+			this.imageData[i * 4] = (byte) r;
 			this.imageData[i * 4 + 1] = (byte) g;
 			this.imageData[i * 4 + 2] = (byte) b;
 			this.imageData[i * 4 + 3] = (byte) a;
diff --git a/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterStill.java b/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterStill.java
index 24bdb87e1..07c381ba6 100644
--- a/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterStill.java
+++ b/game/client/src/main/java/net/minecraft/client/render/dynamictexture/DynamicTextureWaterStill.java
@@ -1,6 +1,7 @@
 package net.minecraft.client.render.dynamictexture;
 
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.texture.stitcher.IconCoordinate;
 
 public class DynamicTextureWaterStill extends DynamicTexture {
@@ -20,10 +21,10 @@ public class DynamicTextureWaterStill extends DynamicTexture {
 	public void postInit() {
 		initTexture();
 
-		arr1 = new float[targetTexture.getArea()];
-		arr2 = new float[targetTexture.getArea()];
-		arr3 = new float[targetTexture.getArea()];
-		arr4 = new float[targetTexture.getArea()];
+        this.arr1 = new float[this.targetTexture.getArea()];
+        this.arr2 = new float[this.targetTexture.getArea()];
+        this.arr3 = new float[this.targetTexture.getArea()];
+        this.arr4 = new float[this.targetTexture.getArea()];
 	}
 
 	@Override
@@ -32,30 +33,30 @@ public class DynamicTextureWaterStill extends DynamicTexture {
 		float bright;
 		int a_;
 		int b_;
-		for (int x = 0; x < targetTexture.width; ++x) {
-			for (y = 0; y < targetTexture.height; ++y) {
+		for (int x = 0; x < this.targetTexture.width; ++x) {
+			for (y = 0; y < this.targetTexture.height; ++y) {
 				bright = 0.0F;
 
 				for (int k = x - 1; k <= x + 1; ++k) {
-					a_ = pmod(k, targetTexture.width);
-					b_ = pmod(y, targetTexture.height);
-					bright += this.arr1[a_ + b_ * targetTexture.width];
+					a_ = pmod(k, this.targetTexture.width);
+					b_ = pmod(y, this.targetTexture.height);
+					bright += this.arr1[a_ + b_ * this.targetTexture.width];
 				}
 
-				this.arr2[x + y * targetTexture.width] = bright / 3.3F + this.arr3[x + y * targetTexture.width] * 0.8F;
+				this.arr2[x + y * this.targetTexture.width] = bright / 3.3F + this.arr3[x + y * this.targetTexture.width] * 0.8F;
 			}
 		}
 
-		for (int x = 0; x < targetTexture.width; ++x) {
-			for (y = 0; y < targetTexture.height; ++y) {
-				this.arr3[x + y * targetTexture.width] += this.arr4[x + y * targetTexture.width] * 0.05F;
-				if (this.arr3[x + y * targetTexture.width] < 0.0F) {
-					this.arr3[x + y * targetTexture.width] = 0.0F;
+		for (int x = 0; x < this.targetTexture.width; ++x) {
+			for (y = 0; y < this.targetTexture.height; ++y) {
+				this.arr3[x + y * this.targetTexture.width] += this.arr4[x + y * this.targetTexture.width] * 0.05F;
+				if (this.arr3[x + y * this.targetTexture.width] < 0.0F) {
+					this.arr3[x + y * this.targetTexture.width] = 0.0F;
 				}
 
-				this.arr4[x + y * targetTexture.width] -= 0.1F;
+				this.arr4[x + y * this.targetTexture.width] -= 0.1F;
 				if (Math.random() < 0.05D) {
-					this.arr4[x + y * targetTexture.width] = 0.5F;
+					this.arr4[x + y * this.targetTexture.width] = 0.5F;
 				}
 			}
 		}
@@ -64,7 +65,7 @@ public class DynamicTextureWaterStill extends DynamicTexture {
 		this.arr2 = this.arr1;
 		this.arr1 = var12;
 
-		for (int i = 0; i < targetTexture.getArea(); ++i) {
+		for (int i = 0; i < this.targetTexture.getArea(); ++i) {
 			bright = this.arr1[i];
 			if (bright > 1.0F) {
 				bright = 1.0F;
@@ -80,11 +81,11 @@ public class DynamicTextureWaterStill extends DynamicTexture {
 			int b = 255;
 			int a = (int) (146.0F + var13 * 50.0F);
 
-			if (mc.gameSettings.biomeWater.value && !(mc.currentWorld != null && mc.currentWorld.isRetro())) {
+			if (GameSettings.BIOME_WATER.value && !(this.mc.currentWorld != null && this.mc.currentWorld.isRetro())) {
 				r = g = b = (r + g + b) / 3;
 			}
 
-			this.imageData[i * 4 + 0] = (byte) r;
+			this.imageData[i * 4] = (byte) r;
 			this.imageData[i * 4 + 1] = (byte) g;
 			this.imageData[i * 4 + 2] = (byte) b;
 			this.imageData[i * 4 + 3] = (byte) a;
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 c01ecfd26..6f760dfcb 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
@@ -1,11 +1,11 @@
 package net.minecraft.client.render.entity;
 
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.font.FontRenderer;
 import net.minecraft.client.render.renderer.BlendFactor;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.Shaders;
 import net.minecraft.client.render.renderer.State;
-import net.minecraft.core.block.Blocks;
 import net.minecraft.core.entity.EntityDispatcher;
 import net.minecraft.core.util.collection.NamespaceID;
 import net.minecraft.core.world.pos.TilePos;
@@ -313,7 +313,7 @@ public abstract class EntityRenderer<T extends Entity> {
     }
 
     public void postRender(final @NotNull TessellatorGeneral tessellator, final @NotNull T entity, final double x, final double y, final double z, final float yaw, final float partialTick) {
-        if (renderShadows && this.renderDispatcher.settings.fancyGraphics.value == 1 && getShadowSize(entity) > 0.0F) {
+        if (renderShadows && GameSettings.ENTITY_SHADOWS.value && getShadowSize(entity) > 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);
             if (opacity > 0.0F) {
diff --git a/game/client/src/main/java/net/minecraft/client/render/entity/EntityRendererFishingBobber.java b/game/client/src/main/java/net/minecraft/client/render/entity/EntityRendererFishingBobber.java
index 57a967328..7f6126c30 100644
--- a/game/client/src/main/java/net/minecraft/client/render/entity/EntityRendererFishingBobber.java
+++ b/game/client/src/main/java/net/minecraft/client/render/entity/EntityRendererFishingBobber.java
@@ -1,5 +1,6 @@
 package net.minecraft.client.render.entity;
 
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.renderer.DrawMode;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.Shaders;
@@ -31,7 +32,7 @@ public class EntityRendererFishingBobber extends EntityRendererSprite<EntityFish
             double xp = MathHelper.lerp(entity.owner.xo, entity.owner.x, partialTick) + vec3.x;
             double yp = MathHelper.lerp(entity.owner.yo, entity.owner.y, partialTick) + entity.owner.getHeadHeight() + vec3.y;
             double zp = MathHelper.lerp(entity.owner.zo, entity.owner.z, partialTick) + vec3.z;
-            if (this.renderDispatcher.settings.thirdPersonView.value > 0) {
+            if (GameSettings.THIRD_PERSON_VIEW.value > 0) {
                 float rr = ((entity.owner.yBodyRotO + (entity.owner.yBodyRot - entity.owner.yBodyRotO) * partialTick) * MathHelper.PI) / 180F;
                 double ss = MathHelper.sin(rr);
                 double cc = MathHelper.cos(rr);
diff --git a/game/client/src/main/java/net/minecraft/client/render/entity/EntityRendererItem.java b/game/client/src/main/java/net/minecraft/client/render/entity/EntityRendererItem.java
index 58e1e346d..11e8c3ac3 100644
--- a/game/client/src/main/java/net/minecraft/client/render/entity/EntityRendererItem.java
+++ b/game/client/src/main/java/net/minecraft/client/render/entity/EntityRendererItem.java
@@ -1,6 +1,6 @@
 package net.minecraft.client.render.entity;
 
-import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.core.entity.EntityItem;
 import org.jetbrains.annotations.NotNull;
@@ -37,7 +37,7 @@ public class EntityRendererItem extends EntityRenderer<EntityItem> {
             renderCount = 4;
         }
         GLRenderer.modelM4f().translate((float) x, (float) (y + bobbingOffset), (float) z);
-        ItemModelDispatcher.getInstance().getDispatch(item).renderItemEntity(tessellator, itemstack, Minecraft.getMinecraft().gameSettings.items3D.value, renderCount, entity.age, yw, entity.getLightmap(partialTick), partialTick);
+        ItemModelDispatcher.getInstance().getDispatch(item).renderItemEntity(tessellator, itemstack, GameSettings.ITEMS_3D.value, renderCount, entity.age, yw, entity.getLightmap(partialTick), partialTick);
         GLRenderer.popFrame();
     }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/render/entity/MobRenderer.java b/game/client/src/main/java/net/minecraft/client/render/entity/MobRenderer.java
index e79f8b6cc..ffc89c256 100644
--- a/game/client/src/main/java/net/minecraft/client/render/entity/MobRenderer.java
+++ b/game/client/src/main/java/net/minecraft/client/render/entity/MobRenderer.java
@@ -2,6 +2,7 @@ package net.minecraft.client.render.entity;
 
 import com.mojang.logging.LogUtils;
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.font.FontRenderer;
 import net.minecraft.client.render.renderer.BlendFactor;
 import net.minecraft.client.render.renderer.CompareFunc;
@@ -225,7 +226,7 @@ public abstract class MobRenderer<T extends Mob> extends EntityRenderer<T> {
     }
 
     public void loadEntityTexture(final @NotNull T entity) {
-        if (!Minecraft.getMinecraft().gameSettings.mobVariants.value) {
+        if (!GameSettings.MOB_VARIANTS.value) {
             bindTexture(entity.getDefaultEntityTexture());
         } else {
             bindTexture(entity.getEntityTexture());
diff --git a/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererButterfly.java b/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererButterfly.java
index e5b64674c..a3a303683 100644
--- a/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererButterfly.java
+++ b/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererButterfly.java
@@ -1,6 +1,6 @@
 package net.minecraft.client.render.entity;
 
-import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.TextureManager;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
@@ -73,7 +73,7 @@ public class MobRendererButterfly extends EntityRenderer<MobButterfly> {
     }
 
     public static String getTexture(final MobButterfly butterfly) {
-        if (!Minecraft.getMinecraft().gameSettings.mobVariants.value) {
+        if (!GameSettings.MOB_VARIANTS.value) {
             return butterfly.getDefaultEntityTexture();
         } else {
             return butterfly.getEntityTexture();
diff --git a/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererPlayer.java b/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererPlayer.java
index 4848aefe5..8c931876f 100644
--- a/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererPlayer.java
+++ b/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererPlayer.java
@@ -1,6 +1,7 @@
 package net.minecraft.client.render.entity;
 
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.Lighting;
 import net.minecraft.client.render.PlayerSkinParser;
 import net.minecraft.client.render.TileEntityRenderDispatcher;
@@ -113,7 +114,7 @@ public class MobRendererPlayer extends MobRendererBipedArmored<Player> {
         if (mc.thePlayer.getGamemode() != Gamemodes.SPECTATOR && entity.getGamemode() == Gamemodes.SPECTATOR) {
             return;
         }
-        if (mc.gameSettings.immersiveMode.drawNames() && mc.activeCamera != null) // Render name
+        if (GameSettings.IMMERSIVE_MODE.drawNames() && mc.activeCamera != null) // Render name
         {
             if (mc.activeCamera instanceof EntityCamera entityCamera && entityCamera.mob == entity) {
                 return;
@@ -317,7 +318,7 @@ public class MobRendererPlayer extends MobRendererBipedArmored<Player> {
         }
 
         public static @Nullable Specials getSpecialsForPlayer(final @NotNull Player player) {
-            if (!Minecraft.getMinecraft().gameSettings.devModels.value || !player.playerConfig.devModelEnabled())
+            if (!GameSettings.DEV_MODELS.value || !player.playerConfig.devModelEnabled())
                 return null;
             if (player.uuid.equals(SHIGN.uuid) || player.username.equals(SHIGN.username)) return SHIGN;
             if (player.uuid.equals(COOKIE.uuid) || player.username.equals(COOKIE.username)) return COOKIE;
@@ -328,7 +329,7 @@ public class MobRendererPlayer extends MobRendererBipedArmored<Player> {
         }
 
         public static @Nullable Specials getSpecialsForMob(final @NotNull Mob mob) {
-            if (!Minecraft.getMinecraft().gameSettings.devModels.value) return null;
+            if (!GameSettings.DEV_MODELS.value) return null;
             if (mob.nickname.equals(SHIGN.username)) return SHIGN;
             if (mob.nickname.equals(COOKIE.username)) return COOKIE;
             if (mob.nickname.equals(THA_BOAR.username)) return THA_BOAR;
diff --git a/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererWolf.java b/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererWolf.java
index f3e27b964..8c44b4b62 100644
--- a/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererWolf.java
+++ b/game/client/src/main/java/net/minecraft/client/render/entity/MobRendererWolf.java
@@ -1,6 +1,6 @@
 package net.minecraft.client.render.entity;
 
-import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.item.model.ItemModelDispatcher;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
@@ -126,7 +126,7 @@ public class MobRendererWolf extends MobRenderer<MobWolf> {
             getModel("main").translateToBone("mouthItem");
             GLRenderer.modelM4f().scale(MobRenderer.ENTITY_RENDER_SCALE, -MobRenderer.ENTITY_RENDER_SCALE, MobRenderer.ENTITY_RENDER_SCALE);
             GLRenderer.enableState(State.BLEND);
-            ItemModelDispatcher.getInstance().getDispatch(itemstack).render(GLRenderer.getTessellator(), entity, itemstack, DisplayPos.GROUND, Minecraft.getMinecraft().gameSettings.items3D.value, 1, entity.getLightmap(partialTick), partialTick, true);
+            ItemModelDispatcher.getInstance().getDispatch(itemstack).render(GLRenderer.getTessellator(), entity, itemstack, DisplayPos.GROUND, GameSettings.ITEMS_3D.value, 1, entity.getLightmap(partialTick), partialTick, true);
             GLRenderer.disableState(State.BLEND);
             GLRenderer.popFrame();
         }
diff --git a/game/client/src/main/java/net/minecraft/client/render/font/FontRendererDefault.java b/game/client/src/main/java/net/minecraft/client/render/font/FontRendererDefault.java
index 6e0d8f18e..52e2f3e1c 100644
--- a/game/client/src/main/java/net/minecraft/client/render/font/FontRendererDefault.java
+++ b/game/client/src/main/java/net/minecraft/client/render/font/FontRendererDefault.java
@@ -1,6 +1,6 @@
 package net.minecraft.client.render.font;
 
-import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.renderer.BlendFactor;
 import net.minecraft.client.render.renderer.DrawMode;
 import net.minecraft.client.render.renderer.GLRenderer;
@@ -717,7 +717,7 @@ public class FontRendererDefault extends FontRenderer {
     }
 
     public @NotNull Font getFont() {
-        return this.font == null ? Minecraft.getMinecraft().gameSettings.font.value : this.font;
+        return this.font == null ? GameSettings.FONT.value : this.font;
     }
 
     public static int decodeHexToInt(final @NotNull CharSequence hexSequence) throws NumberFormatException {
diff --git a/game/client/src/main/java/net/minecraft/client/render/particle/Particle.java b/game/client/src/main/java/net/minecraft/client/render/particle/Particle.java
index 9a03a9a07..9aa8f30be 100644
--- a/game/client/src/main/java/net/minecraft/client/render/particle/Particle.java
+++ b/game/client/src/main/java/net/minecraft/client/render/particle/Particle.java
@@ -150,7 +150,7 @@ public class Particle {
             switch (hitTile.side) {
                 case EAST:
                 case WEST: {
-                    this.x = hitTile.location.x() + hitTile.side.getOffsetX() * 0.01d * this.size;
+                    this.x = hitTile.location.x() + hitTile.side.getOffsetX() * 0.1d * this.size;
                     this.y += yd;
                     this.z += zd;
                     this.xd = 0;
@@ -160,7 +160,7 @@ public class Particle {
                     this.onGround = true;
                 case BOTTOM: {
                     this.x += xd;
-                    this.y = hitTile.location.y() + hitTile.side.getOffsetY() * 0.01d * this.size;
+                    this.y = hitTile.location.y() + hitTile.side.getOffsetY() * 0.1d * this.size;
                     this.z += zd;
                     this.yd = 0;
                     break;
@@ -169,7 +169,7 @@ public class Particle {
                 case NORTH: {
                     this.x += xd;
                     this.y += yd;
-                    this.z = hitTile.location.z() + hitTile.side.getOffsetZ() * 0.01d * this.size;
+                    this.z = hitTile.location.z() + hitTile.side.getOffsetZ() * 0.1d * this.size;
                     this.zd = 0;
                     break;
                 }
@@ -206,6 +206,7 @@ public class Particle {
         final int signY = (int) org.joml.Math.signum(ray.dY);
         final int signZ = (int) org.joml.Math.signum(ray.dZ);
 
+        TilePos qPos = new TilePos();
         TilePos tilePos = new TilePos(ray.oX, ray.oY, ray.oZ);
 
         double sideDistX = -(ray.oX - (tilePos.x + 0.5)) * (1 / ray.dX) + 0.5 * dDistX;
@@ -218,10 +219,18 @@ public class Particle {
 
         Direction direction = Direction.NONE;
         while (dx * dx + dy * dy + dz * dz < length * length + 4) {
-            Block<?> block = this.world.getBlockType(tilePos);
-            if (block != null && collidesWithBlock(block, this.world.getBlockData(tilePos))) {
-                this.aabbs.clear();
-                block.getCollisionAABBs(this.world, tilePos, this.refAABB.setMin(tilePos.x, tilePos.y, tilePos.z).setMax(tilePos.x + 1, tilePos.y + 1, tilePos.z + 1), this.aabbs);
+            this.aabbs.clear();
+            for (int _x = -1; _x <= 1; _x++) {
+                for (int _y = -1; _y <= 1; _y++) {
+                    for (int _z = -1; _z <= 1; _z++) {
+                        Block<?> block = this.world.getBlockType(tilePos.add(_x, _y, _z, qPos));
+                        if (collidesWithBlock(block, this.world.getBlockData(qPos))) {
+                            block.getCollisionAABBs(this.world, qPos, this.refAABB.setMin(qPos.x, qPos.y, qPos.z).setMax(qPos.x + 1, qPos.y + 1, qPos.z + 1), this.aabbs);
+                        }
+                    }
+                }
+            }
+            if (!this.aabbs.isEmpty()) {
                 double tMin = Double.MAX_VALUE;
                 for (int i = 0, aabbsSize = this.aabbs.size(); i < aabbsSize; i++) {
                     if (this.aabbs.get(i).intersectsRay(ray, this.__r)) {
@@ -234,7 +243,6 @@ public class Particle {
                         direction.getSide(),
                         new Vector3d(ray.oX + tMin * ray.dX, ray.oY + tMin * ray.dY, ray.oZ + tMin * ray.dZ));
                 }
-                return null;
             }
 
             if (Double.isFinite(sideDistX) && sideDistX < sideDistY && sideDistX < sideDistZ) {
diff --git a/game/client/src/main/java/net/minecraft/client/render/particle/ParticleBlockBreaking.java b/game/client/src/main/java/net/minecraft/client/render/particle/ParticleBlockBreaking.java
index b919a180e..a61e89499 100644
--- a/game/client/src/main/java/net/minecraft/client/render/particle/ParticleBlockBreaking.java
+++ b/game/client/src/main/java/net/minecraft/client/render/particle/ParticleBlockBreaking.java
@@ -1,6 +1,5 @@
 package net.minecraft.client.render.particle;
 
-import net.minecraft.client.render.ParticleEngine;
 import net.minecraft.client.render.block.color.BlockColorDispatcher;
 import net.minecraft.client.render.block.model.BlockModel;
 import net.minecraft.client.render.block.model.BlockModelDispatcher;
@@ -12,25 +11,26 @@ import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.pos.TilePos;
+import net.minecraft.core.world.pos.TilePosc;
 import org.jetbrains.annotations.NotNull;
 
 public class ParticleBlockBreaking extends Particle {
     private final Block<?> block;
     private final Side side;
-    private TilePos initPos = new TilePos(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
+    private final @NotNull TilePos initPos = new TilePos(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
 
     public ParticleBlockBreaking(World world, double x, double y, double z, double xa, double ya, double za, Block<?> block, Side side, int meta) {
         super(world, x, y, z, xa, ya, za);
         this.side = side;
         this.block = block;
         this.tex = BlockModelDispatcher.getInstance().getDispatch(block).getParticleTexture(this.side, meta);
-        this.gravity = block != null ? block.blockParticleGravity : 0;
+        this.gravity = block.blockParticleGravity;
         this.rCol = this.gCol = this.bCol = 0.6F;
         this.size /= 2.0F;
     }
 
-    public ParticleBlockBreaking init(@NotNull TilePos tilePos) {
-        this.initPos = tilePos;
+    public ParticleBlockBreaking init(@NotNull TilePosc tilePos) {
+        this.initPos.set(tilePos);
         int meta = this.world.getBlockData(tilePos);
         BlockModel<?> model = BlockModelDispatcher.getInstance().getDispatch(this.block);
         int index = model.particleColorIndex(this.world, tilePos, this.side, meta);
diff --git a/game/client/src/main/java/net/minecraft/client/render/particle/ParticleDispatcher.java b/game/client/src/main/java/net/minecraft/client/render/particle/ParticleDispatcher.java
index beb82d684..69a295c2c 100644
--- a/game/client/src/main/java/net/minecraft/client/render/particle/ParticleDispatcher.java
+++ b/game/client/src/main/java/net/minecraft/client/render/particle/ParticleDispatcher.java
@@ -1,6 +1,8 @@
 package net.minecraft.client.render.particle;
 
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
+import net.minecraft.client.option.enums.ParticlesQuality;
 import net.minecraft.client.render.block.color.BlockColorDispatcher;
 import net.minecraft.client.render.texture.stitcher.TextureRegistry;
 import net.minecraft.client.util.dispatch.Dispatcher;
@@ -10,14 +12,21 @@ import net.minecraft.core.item.Item;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.util.helper.BlockParticleHelper;
 import net.minecraft.core.util.helper.MathHelper;
+import net.minecraft.core.world.World;
 import net.minecraft.core.world.pos.TilePos;
+import org.jetbrains.annotations.NotNull;
 
 import java.util.ArrayList;
 import java.util.List;
 
-public final class ParticleDispatcher extends Dispatcher<String, ParticleLambda> {
+public final class ParticleDispatcher extends Dispatcher<String, ParticleEntry> {
     private static ParticleDispatcher INSTANCE = new ParticleDispatcher();
-    private static final ParticleLambda BLANK = (world, x, y, z, motionX, motionY, motionZ, data) -> null;
+    private static final ParticleEntry BLANK = new ParticleEntry() {
+        @Override
+        public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+            return null;
+        }
+    };
 
     public static ParticleDispatcher getInstance() {
         return INSTANCE;
@@ -28,54 +37,200 @@ public final class ParticleDispatcher extends Dispatcher<String, ParticleLambda>
     }
 
     @Override
-    protected ParticleLambda getDefault() {
+    protected ParticleEntry getDefault() {
         return BLANK;
     }
 
     private ParticleDispatcher() {
         INSTANCE = this;
         Minecraft mc = Minecraft.getMinecraft();
-        addDispatch("bubble", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleBubble(world, x, y, z, motionX, motionY, motionZ, true));
-        addDispatch("smoke", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleSmoke(world, x, y, z, motionX, motionY, motionZ, 1.0f, data));
-        addDispatch("note", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleNote(world, x, y, z, motionX, motionY, motionZ, data));
-        addDispatch("portal", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticlePortal(world, x, y, z, motionX, motionY, motionZ, data));
-        addDispatch("explode", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleExplode(world, x, y, z, motionX, motionY, motionZ));
-        addDispatch("flame", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleFlame(world, x, y, z, motionX, motionY, motionZ, ParticleFlame.Type.ORANGE));
-        addDispatch("blueflame", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleFlame(world, x, y, z, motionX, motionY, motionZ, ParticleFlame.Type.BLUE));
-        addDispatch("soulflame", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleFlame(world, x, y, z, motionX, motionY, motionZ, ParticleFlame.Type.SOUL));
-        addDispatch("lava", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleLava(world, x, y, z));
-        addDispatch("footstep", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleFootstep(mc.textureManager, world, x, y, z));
-        addDispatch("splash", (world1, x, y, z, motionX, motionY, motionZ, data) -> new ParticleSplash(world1, x, y, z, motionX, motionY, motionZ));
-        addDispatch("largesmoke", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleSmoke(world, x, y, z, motionX, motionY, motionZ, 2.5f, data));
-        addDispatch("puffrgb", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticlePuffRGB(world, x, y, z, (float) motionX, (float) motionY, (float) motionZ, data));
-        addDispatch("reddust", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleRedstoneDust(world, x, y, z, data));
-        addDispatch("item", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleItemBreaking(world, x, y, z, Item.itemsList[MathHelper.clamp(data, 0, Item.itemsList.length - 1)]));
-        addDispatch("block", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleBlockBreaking(world, x, y, z, motionX, motionY, motionZ, Blocks.blocksList[BlockParticleHelper.decodeBlockID(data)], BlockParticleHelper.decodeBlockSide(data), BlockParticleHelper.decodeBlockMeta(data)).init(new TilePos(x, y, z)));
-        addDispatch("snowshovel", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleSnowShovel(world, x, y, z, motionX, motionY, motionZ));
-        addDispatch("heart", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleHeart(world, x, y, z, motionX, motionY, motionZ));
-        addDispatch("slimechunk", (world, x, y, z, motionX, motionY, motionZ, data) -> {
-            if (mc.gameSettings.slimeParticles.value) {
+        addDispatch("bubble", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleBubble(world, x, y, z, motionX, motionY, motionZ, true);
+            }
+        });
+        addDispatch("smoke", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleSmoke(world, x, y, z, motionX, motionY, motionZ, 1.0f, data);
+            }
+        });
+        addDispatch("note", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleNote(world, x, y, z, motionX, motionY, motionZ, data);
+            }
+        });
+        addDispatch("portal", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticlePortal(world, x, y, z, motionX, motionY, motionZ, data);
+            }
+        });
+        addDispatch("explode", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleExplode(world, x, y, z, motionX, motionY, motionZ);
+            }
+        });
+        addDispatch("flame", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleFlame(world, x, y, z, motionX, motionY, motionZ, ParticleFlame.Type.ORANGE);
+            }
+        });
+        addDispatch("blueflame", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleFlame(world, x, y, z, motionX, motionY, motionZ, ParticleFlame.Type.BLUE);
+            }
+        });
+        addDispatch("soulflame", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleFlame(world, x, y, z, motionX, motionY, motionZ, ParticleFlame.Type.SOUL);
+            }
+        });
+        addDispatch("lava", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleLava(world, x, y, z);
+            }
+        });
+        addDispatch("footstep", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleFootstep(mc.textureManager, world, x, y, z);
+            }
+        });
+        addDispatch("splash", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleSplash(world, x, y, z, motionX, motionY, motionZ);
+            }
+        });
+        addDispatch("largesmoke", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleSmoke(world, x, y, z, motionX, motionY, motionZ, 2.5f, data);
+            }
+        });
+        addDispatch("puffrgb", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticlePuffRGB(world, x, y, z, (float) motionX, (float) motionY, (float) motionZ, data);
+            }
+        });
+        addDispatch("reddust", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleRedstoneDust(world, x, y, z, data);
+            }
+        });
+        addDispatch("item", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleItemBreaking(world, x, y, z, Item.itemsList[MathHelper.clamp(data, 0, Item.itemsList.length - 1)]);
+            }
+        });
+        addDispatch("block", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleBlockBreaking(world, x, y, z, motionX, motionY, motionZ, Blocks.blocksList[BlockParticleHelper.decodeBlockID(data)], BlockParticleHelper.decodeBlockSide(data), BlockParticleHelper.decodeBlockMeta(data)).init(new TilePos(x, y, z));
+            }
+        });
+        addDispatch("snowshovel", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleSnowShovel(world, x, y, z, motionX, motionY, motionZ);
+            }
+        });
+        addDispatch("heart", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleHeart(world, x, y, z, motionX, motionY, motionZ);
+            }
+
+            @Override
+            public boolean enabled() {
+                return GameSettings.PARTICLES_QUALITY.value != ParticlesQuality.NONE;
+            }
+        });
+        addDispatch("slimechunk", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
                 return new ParticleSlimeChunk(world, x, y, z, Items.SLIMEBALL);
             }
-            return null;
+
+            @Override
+            public boolean enabled() {
+                return GameSettings.SLIME_PARTICLES.value;
+            }
         });
-        addDispatch("fireflyGreen", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleFirefly(world, x, y, z, motionX, motionY, motionZ, MobFireflyCluster.FireflyColor.GREEN.getId()));
-        addDispatch("fireflyBlue", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleFirefly(world, x, y, z, motionX, motionY, motionZ, MobFireflyCluster.FireflyColor.BLUE.getId()));
-        addDispatch("fireflyOrange", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleFirefly(world, x, y, z, motionX, motionY, motionZ, MobFireflyCluster.FireflyColor.ORANGE.getId()));
-        addDispatch("fireflyRed", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleFirefly(world, x, y, z, motionX, motionY, motionZ, MobFireflyCluster.FireflyColor.RED.getId()));
-        addDispatch("arrowtrail", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleArrowGolden(world, x, y, z, motionX, motionY, motionZ));
-        addDispatch("fallingleaf", (world, x, y, z, motionX, motionY, motionZ, data) -> {
-            TilePos tilePos = new TilePos(x, y, z);
-            if (!world.isAirBlock(tilePos)) {
-                return new ParticleLeaf(world, x, y, z, motionX, motionY, motionZ).init(tilePos);
+        addDispatch("fireflyGreen", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleFirefly(world, x, y, z, motionX, motionY, motionZ, MobFireflyCluster.FireflyColor.GREEN.getId());
+            }
+        });
+        addDispatch("fireflyBlue", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleFirefly(world, x, y, z, motionX, motionY, motionZ, MobFireflyCluster.FireflyColor.BLUE.getId());
             }
-            return null;
         });
-        addDispatch("dripWater", (world, x, y, z, motionX, motionY, motionZ, data) -> {
-            int color = BlockColorDispatcher.getInstance().getDispatch(Blocks.FLUID_WATER_STILL).getWorldColor(world, MathHelper.floor(x), MathHelper.floor(y), MathHelper.floor(z), 0);
-            return new ParticleFluidDrip(world, x, y, z, color, TextureRegistry.getTexture("minecraft:block/water_flowing"));
+        addDispatch("fireflyOrange", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleFirefly(world, x, y, z, motionX, motionY, motionZ, MobFireflyCluster.FireflyColor.ORANGE.getId());
+            }
+        });
+        addDispatch("fireflyRed", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleFirefly(world, x, y, z, motionX, motionY, motionZ, MobFireflyCluster.FireflyColor.RED.getId());
+            }
+        });
+        addDispatch("arrowtrail", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleArrowGolden(world, x, y, z, motionX, motionY, motionZ);
+            }
+
+            @Override
+            public boolean enabled() {
+                return GameSettings.PARTICLES_QUALITY.value != ParticlesQuality.NONE;
+            }
+        });
+        addDispatch("fallingleaf", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                TilePos tilePos = new TilePos(x, y, z);
+                if (!world.isAirBlock(tilePos)) {
+                    return new ParticleLeaf(world, x, y, z, motionX, motionY, motionZ).init(tilePos);
+                }
+                return null;
+            }
+        });
+        addDispatch("dripWater", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                int color = BlockColorDispatcher.getInstance().getDispatch(Blocks.FLUID_WATER_STILL).getWorldColor(world, new TilePos(x, y, z), 0);
+                return new ParticleFluidDrip(world, x, y, z, color, TextureRegistry.getTexture("minecraft:block/water_flowing"));
+            }
+        });
+        addDispatch("dripLava", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleFluidDrip(world, x, y, z, 0xFFFFFF, TextureRegistry.getTexture("minecraft:block/lava_flowing")).setFullBright();
+            }
+        });
+        addDispatch("ashmote", new ParticleEntry() {
+            @Override
+            public Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data) {
+                return new ParticleAsh(world, x, y, z, 0, 0, 0);
+            }
         });
-        addDispatch("dripLava", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleFluidDrip(world, x, y, z, 0xFFFFFF, TextureRegistry.getTexture("minecraft:block/lava_flowing")).setFullBright());
-        addDispatch("ashmote", (world, x, y, z, motionX, motionY, motionZ, data) -> new ParticleAsh(world, x, y, z, 0, 0, 0));
     }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/render/particle/ParticleEntry.java b/game/client/src/main/java/net/minecraft/client/render/particle/ParticleEntry.java
new file mode 100644
index 000000000..23b8917d5
--- /dev/null
+++ b/game/client/src/main/java/net/minecraft/client/render/particle/ParticleEntry.java
@@ -0,0 +1,13 @@
+package net.minecraft.client.render.particle;
+
+import net.minecraft.client.option.GameSettings;
+import net.minecraft.client.option.enums.ParticlesQuality;
+import net.minecraft.core.world.World;
+import org.jetbrains.annotations.NotNull;
+
+public abstract class ParticleEntry {
+    public abstract Particle newParticle(@NotNull World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data);
+    public boolean enabled() {
+        return GameSettings.PARTICLES_QUALITY.value == ParticlesQuality.ALL;
+    }
+}
diff --git a/game/client/src/main/java/net/minecraft/client/render/particle/ParticleLambda.java b/game/client/src/main/java/net/minecraft/client/render/particle/ParticleLambda.java
deleted file mode 100644
index fda0064ad..000000000
--- a/game/client/src/main/java/net/minecraft/client/render/particle/ParticleLambda.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package net.minecraft.client.render.particle;
-
-import net.minecraft.core.world.World;
-
-@FunctionalInterface
-public interface ParticleLambda {
-    Particle newParticle(World world, double x, double y, double z, double motionX, double motionY, double motionZ, int data);
-}
diff --git a/game/client/src/main/java/net/minecraft/client/render/renderer/GLRenderer.java b/game/client/src/main/java/net/minecraft/client/render/renderer/GLRenderer.java
index f60caeff7..25868a062 100644
--- a/game/client/src/main/java/net/minecraft/client/render/renderer/GLRenderer.java
+++ b/game/client/src/main/java/net/minecraft/client/render/renderer/GLRenderer.java
@@ -2,6 +2,7 @@ package net.minecraft.client.render.renderer;
 
 import com.mojang.logging.LogUtils;
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.FogManager;
 import net.minecraft.client.render.Lighting;
 import net.minecraft.client.render.LightmapHelper;
@@ -156,7 +157,7 @@ public class GLRenderer {
         shader.uniformFloat("uPartialTick", instance.mc.timer.partialTicks);
         shader.uniformFloat("uLineWidth", instance.currentLineWidth);
 
-        double renderScale = (float) instance.mc.gameSettings.renderScale.value.scale;
+        double renderScale = (float) GameSettings.RENDER_SCALE.value.scale;
         int scaledWidth = (int) (renderScale * instance.mc.gameWindow.getWidthPixels());
         int scaledHeight = (int) (renderScale * instance.mc.gameWindow.getHeightPixels());
         shader.uniformVec2f("uViewPortSize", scaledWidth, scaledHeight);
diff --git a/game/client/src/main/java/net/minecraft/client/render/shader/ShaderHelper.java b/game/client/src/main/java/net/minecraft/client/render/shader/ShaderHelper.java
index 17d9258b2..be7dd11e3 100644
--- a/game/client/src/main/java/net/minecraft/client/render/shader/ShaderHelper.java
+++ b/game/client/src/main/java/net/minecraft/client/render/shader/ShaderHelper.java
@@ -3,13 +3,13 @@ package net.minecraft.client.render.shader;
 
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.ScreenPhotoMode;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.camera.CameraUtil;
 import net.minecraft.client.render.renderer.DrawMode;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.client.render.renderer.State;
 import net.minecraft.client.render.tessellator.RenderBuffer;
 import net.minecraft.core.block.Blocks;
-import net.minecraft.core.block.material.Material;
 import net.minecraft.core.block.material.Materials;
 import net.minecraft.core.enums.HumanArmorShape;
 import net.minecraft.core.item.ItemStack;
@@ -73,12 +73,12 @@ public final class ShaderHelper {
         shader.uniformFloat("width", minecraft.gameWindow.getWidthPixels());
         shader.uniformFloat("height", minecraft.gameWindow.getHeightPixels());
         shader.uniformFloat("frameTimeCounter", frameTimeCounter);
-        shader.uniformFloat("gamma", minecraft.gameSettings.gamma.value);
-        shader.uniformFloat("fxaa", minecraft.gameSettings.fxaa.value);
-        shader.uniformFloat("heatHaze", minecraft.gameSettings.heatHaze.value ? minecraft.ppm.lerped.heatHaze : 0.0f);
-        shader.uniformInt("bloom", minecraft.gameSettings.bloom.value);
+        shader.uniformFloat("gamma", GameSettings.GAMMA.value);
+        shader.uniformFloat("fxaa", GameSettings.FXAA.value);
+        shader.uniformFloat("heatHaze", GameSettings.HEAT_HAZE.value ? minecraft.ppm.lerped.heatHaze : 0.0f);
+        shader.uniformInt("bloom", GameSettings.BLOOM.value);
         shader.uniformInt("dimension", minecraft.currentWorld != null && minecraft.currentWorld.dimension != null ? minecraft.currentWorld.dimension.id : 0);
-        shader.uniformInt("cbCorrectionMode", minecraft.gameSettings.colorblindnessFix.value.ordinal());
+        shader.uniformInt("cbCorrectionMode", GameSettings.COLORBLINDNESS_FIX.value.ordinal());
 
         ItemStack helmet = minecraft.thePlayer == null ? null : minecraft.thePlayer.getItemInArmorSlot(HumanArmorShape.HEAD);
         shader.uniformInt("shaderEffect", helmet != null && helmet.itemID == Blocks.PUMPKIN_REDSTONE.id() ? 1 : 0);
diff --git a/game/client/src/main/java/net/minecraft/client/render/shader/ShadersRenderer.java b/game/client/src/main/java/net/minecraft/client/render/shader/ShadersRenderer.java
index 397d2cc2a..d40b63b47 100644
--- a/game/client/src/main/java/net/minecraft/client/render/shader/ShadersRenderer.java
+++ b/game/client/src/main/java/net/minecraft/client/render/shader/ShadersRenderer.java
@@ -1,21 +1,22 @@
 package net.minecraft.client.render.shader;
 
-import java.io.File;
-
 import com.mojang.logging.LogUtils;
-import net.minecraft.client.render.LightmapHelper;
-import net.minecraft.client.render.renderer.Shaders;
-import net.minecraft.core.block.material.Materials;
-
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
+import net.minecraft.client.option.enums.CloudQuality;
 import net.minecraft.client.render.FrameBuffer;
+import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.OpenGLHelper;
 import net.minecraft.client.render.Renderer;
-import net.minecraft.client.render.texture.Texture;
 import net.minecraft.client.render.camera.CameraUtil;
+import net.minecraft.client.render.renderer.Shaders;
+import net.minecraft.client.render.texture.Texture;
+import net.minecraft.core.block.material.Materials;
 import org.lwjgl.opengl.GL41;
 import org.slf4j.Logger;
 
+import java.io.File;
+
 public class ShadersRenderer implements Renderer {
     private static final Logger LOGGER = LogUtils.getLogger();
     public Minecraft mc;
@@ -138,7 +139,7 @@ public class ShadersRenderer implements Renderer {
 
     @Override
     public void beginRenderClouds(float partialTicks) {
-        if (this.mc.gameSettings.clouds.value && this.mc.gameSettings.fancyGraphics.value == 1 && Shaders.CLOUDS.isEnabled()) {
+        if (GameSettings.CLOUDS.value && GameSettings.CLOUD_QUALITY.value == CloudQuality.FANCY && Shaders.CLOUDS.isEnabled()) {
             OpenGLHelper.checkError("pre setup clouds");
 
             // Alpha test is implemented in the shader because regular alpha test removes some pixels at the edge
@@ -175,7 +176,7 @@ public class ShadersRenderer implements Renderer {
     }
 
     public void setupFramebuffer() {
-        double renderScale = (float) this.mc.gameSettings.renderScale.value.scale;
+        double renderScale = (float) GameSettings.RENDER_SCALE.value.scale;
 
         int scaledWidth = (int) (renderScale * this.mc.gameWindow.getWidthPixels());
         int scaledHeight = (int) (renderScale * this.mc.gameWindow.getHeightPixels());
@@ -195,7 +196,7 @@ public class ShadersRenderer implements Renderer {
             this.renderWidth = scaledWidth;
             this.renderHeight = scaledHeight;
 
-            boolean filtering = this.mc.gameSettings.renderScale.value.useLinearFiltering;
+            boolean filtering = GameSettings.RENDER_SCALE.value.useLinearFiltering;
             int filterMode = filtering ? GL41.GL_LINEAR : GL41.GL_NEAREST;
 
             LOGGER.info("Display: {} x {}, Render: {} x {}", this.fbWidth, this.fbHeight, this.renderWidth, this.renderHeight);
@@ -278,7 +279,7 @@ public class ShadersRenderer implements Renderer {
     }
 
     public ShaderProvider getShader() {
-        String override = this.mc.gameSettings.shaderOverride.value;
+        String override = GameSettings.SHADER_OVERRIDE.value;
         if (!override.isEmpty()) {
             return new ShaderProviderExternal(new File(override));
         } else {
diff --git a/game/client/src/main/java/net/minecraft/client/render/terrain/TerrainRendererMultiDraw.java b/game/client/src/main/java/net/minecraft/client/render/terrain/TerrainRendererMultiDraw.java
index caf724961..084b46697 100644
--- a/game/client/src/main/java/net/minecraft/client/render/terrain/TerrainRendererMultiDraw.java
+++ b/game/client/src/main/java/net/minecraft/client/render/terrain/TerrainRendererMultiDraw.java
@@ -1,19 +1,19 @@
 package net.minecraft.client.render.terrain;
 
-import java.util.Arrays;
-import java.util.List;
-
-import net.minecraft.client.render.renderer.GLRenderer;
-import net.minecraft.client.render.renderer.Shaders;
-import net.minecraft.core.block.entity.TileEntity;
-
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.camera.ICamera;
+import net.minecraft.client.render.renderer.GLRenderer;
+import net.minecraft.client.render.renderer.Shaders;
 import net.minecraft.client.render.terrain.VertexBuffer.Entry;
 import net.minecraft.client.render.tessellator.TessellatorTerrainImpl;
+import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.World;
 
+import java.util.Arrays;
+import java.util.List;
+
 public class TerrainRendererMultiDraw extends TerrainRenderer {
 
     public final int VERTEX_BUFFER_INITIAL_CAPACITY = 67108864;
@@ -134,15 +134,13 @@ public class TerrainRendererMultiDraw extends TerrainRenderer {
 
         this.terrainVertexConfig.enable(this.vertexBuffer.getVao(), this.vertexBuffer.getVbo());
 
-        boolean fancy = this.mc.gameSettings.fancyGraphics.value != 0;
-
-        if (fancy) {
+        if (GameSettings.TRANSPARENCY_DEPTH_CHECK.value) {
             GLRenderer.setColorMask(false, false, false, false);
         }
 
         renderAllLists(1);
 
-        if (fancy) {
+        if (GameSettings.TRANSPARENCY_DEPTH_CHECK.value) {
             GLRenderer.setColorMask(true, true, true, true);
             if (this.drawCalls[1] > 0) {
                 renderAllLists(1);
diff --git a/game/client/src/main/java/net/minecraft/client/render/texture/Texture.java b/game/client/src/main/java/net/minecraft/client/render/texture/Texture.java
index c6c90092a..1be432f97 100644
--- a/game/client/src/main/java/net/minecraft/client/render/texture/Texture.java
+++ b/game/client/src/main/java/net/minecraft/client/render/texture/Texture.java
@@ -7,7 +7,7 @@ import static org.lwjgl.opengl.GL41.GL_TEXTURE_MAX_LEVEL;
 
 import com.mojang.logging.LogUtils;
 import net.minecraft.client.GLAllocation;
-import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.option.enums.MipmapType;
 import net.minecraft.client.render.texture.meta.TextureProperties;
 import net.minecraft.client.util.helper.Buffer;
@@ -138,8 +138,7 @@ public class Texture {
 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
 
 		if(mipmap) {
-			Minecraft mc = Minecraft.getMinecraft();
-			generateMipmaps(buffer, img, mc.gameSettings.mipmapLevels.value, mc.gameSettings.mipmapType.value == MipmapType.SMOOTH);
+			generateMipmaps(buffer, img, GameSettings.MIPMAP_LEVELS.value, GameSettings.MIPMAP_TYPE.value == MipmapType.SMOOTH);
 		}
 	}
 
diff --git a/game/client/src/main/java/net/minecraft/client/render/texture/stitcher/AtlasStitcher.java b/game/client/src/main/java/net/minecraft/client/render/texture/stitcher/AtlasStitcher.java
index 5e2d5fff6..d5c89844f 100644
--- a/game/client/src/main/java/net/minecraft/client/render/texture/stitcher/AtlasStitcher.java
+++ b/game/client/src/main/java/net/minecraft/client/render/texture/stitcher/AtlasStitcher.java
@@ -9,7 +9,6 @@ import java.util.List;
 import java.util.Map;
 
 import com.mojang.logging.LogUtils;
-import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
 import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
 import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
@@ -244,15 +243,6 @@ public class AtlasStitcher {
         return image;
     }
 
-    public int[] getIconData(@NotNull String layer, @NotNull IconCoordinate coordinate, int[] dest) {
-        BufferedImage img = this.layerImageMap.get(layer);
-        if (img != null) {
-            assert dest.length >= coordinate.getArea();
-            img.getRGB(coordinate.iconX, coordinate.iconY, coordinate.width, coordinate.height, dest, 0, coordinate.width);
-        }
-        return dest;
-    }
-
     public void bind() {
         this.colorTexture.bind();
     }
diff --git a/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePack.java b/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePack.java
index f4f856b27..9b4fbe3ef 100644
--- a/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePack.java
+++ b/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePack.java
@@ -14,6 +14,7 @@ import java.util.stream.Stream;
 import com.mojang.logging.LogUtils;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.holiday.Holidays;
+import net.minecraft.client.option.GameSettings;
 import org.jetbrains.annotations.Nullable;
 import org.slf4j.Logger;
 
@@ -47,7 +48,7 @@ public abstract class TexturePack {
 
 	public @Nullable InputStream getResourceAsStream(String s)
 	{
-		if (Holidays.getCurrentThemedHoliday() != null && Minecraft.getMinecraft().gameSettings.enableHolidayTextures.value) {
+		if (Holidays.getCurrentThemedHoliday() != null && GameSettings.ENABLE_HOLIDAY_TEXTURES.value) {
 			assert Holidays.getCurrentThemedHoliday().getCustomResourcesSubPath() != null : "Current themed holiday must have a theme!";
 			String holidayPath = ("/holidays/" + Holidays.getCurrentThemedHoliday().getCustomResourcesSubPath() + "/" + s).replace("//", "/");
 			InputStream holidayStream = TexturePack.class.getResourceAsStream(holidayPath);
@@ -101,7 +102,7 @@ public abstract class TexturePack {
 		}
 		catch (Exception e)
 		{
-            LOGGER.error("Exception while loading all files in directory '{}' at '{}'!", directory, packId, e);
+            LOGGER.error("Exception while loading all files in directory '{}' at '{}'!", directory, this.packId, e);
 		}
 
 		return paths.toArray(new String[0]);
diff --git a/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePackCustom.java b/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePackCustom.java
index 276f0eb0c..8d76648dc 100644
--- a/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePackCustom.java
+++ b/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePackCustom.java
@@ -16,298 +16,250 @@ import java.util.zip.ZipFile;
 import com.mojang.logging.LogUtils;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.holiday.Holidays;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.texture.TextureBuffered;
 import net.minecraft.client.render.texturepack.Manifest.ManifestException;
 import org.slf4j.Logger;
 
 import javax.imageio.ImageIO;
 
-public class TexturePackCustom extends TexturePack
-{
-	private static final Logger LOGGER = LogUtils.getLogger();
-	private TextureBuffered thumbnailImage;
-	private BufferedImage thumbnailBuffer;
-	public final File file;
-	private ZipFile zipFile;
-	public boolean debug = false;
+public class TexturePackCustom extends TexturePack {
+    private static final Logger LOGGER = LogUtils.getLogger();
+    private TextureBuffered thumbnailImage;
+    private BufferedImage thumbnailBuffer;
+    public final File file;
+    private ZipFile zipFile;
+    public boolean debug = false;
 
-    public TexturePackCustom(File file)
-    {
-        thumbnailImage = null;
-        fileName = file.getName();
+    public TexturePackCustom(File file) {
+        this.thumbnailImage = null;
+        this.fileName = file.getName();
         this.file = file;
     }
 
-	public void setDebug() {
-		debug = true;
-	}
+    public void setDebug() {
+        this.debug = true;
+    }
 
-	@Override
-	public void readTexturePackManifest()
-		throws IOException {
-		if (file.isFile()) {
-			// Texture pack is zip file
-			ZipEntry manifestEntry = zipFile.getEntry("manifest.json");
-			if(manifestEntry != null) {
-				// manifest.json exists
+    @Override
+    public void readTexturePackManifest()
+        throws IOException {
+        if (this.file.isFile()) {
+            // Texture pack is zip file
+            ZipEntry manifestEntry = this.zipFile.getEntry("manifest.json");
+            if (manifestEntry != null) {
+                // manifest.json exists
 
-                try (InputStream in = zipFile.getInputStream(manifestEntry)) {
+                try (InputStream in = this.zipFile.getInputStream(manifestEntry)) {
                     readManifest(in);
                 } catch (Exception e) {
-                    LOGGER.error("Exception reading manifest for '{}'!", packId, e);
+                    LOGGER.error("Exception reading manifest for '{}'!", this.packId, e);
                 }
-			}else {
-				// Assume it's an old texture pack
+            } else {
+                // Assume it's an old texture pack
 
-				String name = file.getName();
-				String line1 = "";
-				String line2 = "";
-				
-				ZipEntry packTxtEntry = zipFile.getEntry("pack.txt");
-				if(packTxtEntry != null) {
-                    try (InputStream in = zipFile.getInputStream(packTxtEntry); BufferedReader br = new BufferedReader(new InputStreamReader(in))) {
+                String name = this.file.getName();
+                String line1 = "";
+                String line2 = "";
+
+                ZipEntry packTxtEntry = this.zipFile.getEntry("pack.txt");
+                if (packTxtEntry != null) {
+                    try (InputStream in = this.zipFile.getInputStream(packTxtEntry); BufferedReader br = new BufferedReader(new InputStreamReader(in))) {
                         line1 = br.readLine();
                         line2 = br.readLine();
                     } catch (Exception e) {
-                        LOGGER.error("Exception reading pack.txt for '{}'!", packId, e);
+                        LOGGER.error("Exception reading pack.txt for '{}'!", this.packId, e);
                     }
-				}
-				
-				this.manifest = new ManifestFallback(name, line1, line2, 0);
-			}
-		} else if (file.isDirectory()) {
-			File manifestFile = new File(this.file, "manifest.json");
-			if(manifestFile.exists()) {
+                }
+
+                this.manifest = new ManifestFallback(name, line1, line2, 0);
+            }
+        } else if (this.file.isDirectory()) {
+            File manifestFile = new File(this.file, "manifest.json");
+            if (manifestFile.exists()) {
                 try (InputStream in = Files.newInputStream(manifestFile.toPath())) {
                     readManifest(in);
                 } catch (Exception e) {
-                    LOGGER.error("Exception reading manifest for '{}'!", packId, e);
+                    LOGGER.error("Exception reading manifest for '{}'!", this.packId, e);
                 }
-			}else {
-				// Assume its an old texture pack
+            } else {
+                // Assume its an old texture pack
+
+                String name = this.file.getName();
+                String line1 = "";
+                String line2 = "";
 
-				String name = file.getName();
-				String line1 = "";
-				String line2 = "";
-				
-				File packTxtFile = new File(this.file, "pack.txt");
-				if(packTxtFile.exists()) {
+                File packTxtFile = new File(this.file, "pack.txt");
+                if (packTxtFile.exists()) {
                     try (InputStream in = Files.newInputStream(packTxtFile.toPath()); BufferedReader br = new BufferedReader(new InputStreamReader(in))) {
                         line1 = br.readLine();
                         line2 = br.readLine();
                     } catch (Exception e) {
-                        LOGGER.error("Exception reading pack.txt for '{}'!", packId, e);
+                        LOGGER.error("Exception reading pack.txt for '{}'!", this.packId, e);
                     }
-				}
-				
-				this.manifest = new ManifestFallback(name, line1, line2, 0);
-			}
-		}
-		try {
-			InputStream inputstream = getResourceAsStream("pack.png");
+                }
+
+                this.manifest = new ManifestFallback(name, line1, line2, 0);
+            }
+        }
+        try {
+            InputStream inputstream = getResourceAsStream("pack.png");
+
+            try {
+                this.thumbnailBuffer = ImageIO.read(inputstream);
+            } catch (Throwable var8) {
+                try {
+                    inputstream.close();
+                } catch (Throwable var6) {
+                    var8.addSuppressed(var6);
+                }
 
-			try {
-				this.thumbnailBuffer = ImageIO.read(inputstream);
-			} catch (Throwable var8) {
-				try {
-					inputstream.close();
-				} catch (Throwable var6) {
-					var8.addSuppressed(var6);
-				}
+                throw var8;
+            }
 
-				throw var8;
-			}
+            inputstream.close();
+        } catch (Exception ignored) {
+        }
+    }
 
-			inputstream.close();
-		} catch (Exception ignored) {
-		}
-	}
-	
-	private void readManifest(InputStream in) {
-		try {
-			this.manifest = new Manifest(file, in);
-		}catch (ManifestException e) {
-			this.manifest = new ManifestFallback(fileName, "Manifest Error: " + e.getMessage(), "", -1);
-			LOGGER.error("Manifest Error!", e);
-		}catch (Exception e) {
-			this.manifest = new ManifestFallback(fileName, "Manifest Error", "", -1);
-			LOGGER.error("Manifest Error!", e);
-		}
-	}
+    private void readManifest(InputStream in) {
+        try {
+            this.manifest = new Manifest(this.file, in);
+        } catch (ManifestException e) {
+            this.manifest = new ManifestFallback(this.fileName, "Manifest Error: " + e.getMessage(), "", -1);
+            LOGGER.error("Manifest Error!", e);
+        } catch (Exception e) {
+            this.manifest = new ManifestFallback(this.fileName, "Manifest Error", "", -1);
+            LOGGER.error("Manifest Error!", e);
+        }
+    }
 
-	@Override
-	public void disposeOfTexturePack(Minecraft minecraft)
-    {
-        if(thumbnailBuffer != null)
-        {
-			thumbnailImage.delete();
-			thumbnailImage = null;
+    @Override
+    public void disposeOfTexturePack(Minecraft minecraft) {
+        if (this.thumbnailBuffer != null) {
+            this.thumbnailImage.delete();
+            this.thumbnailImage = null;
         }
         closeTexturePackFile();
     }
 
     @Override
-	public void bindThumbnailTexture(Minecraft minecraft)
-    {
-        if(thumbnailBuffer != null && thumbnailImage == null)
-        {
-            thumbnailImage = minecraft.textureManager.loadBufferedTexture(thumbnailBuffer);
+    public void bindThumbnailTexture(Minecraft minecraft) {
+        if (this.thumbnailBuffer != null && this.thumbnailImage == null) {
+            this.thumbnailImage = minecraft.textureManager.loadBufferedTexture(this.thumbnailBuffer);
         }
-        if(thumbnailBuffer != null)
-        {
-            minecraft.textureManager.bindTexture(thumbnailImage);
-        } else
-        {
-			minecraft.textureManager.loadTexture("/assets/minecraft/textures/gui/unknown_pack.png").bind();
+        if (this.thumbnailBuffer != null) {
+            minecraft.textureManager.bindTexture(this.thumbnailImage);
+        } else {
+            minecraft.textureManager.loadTexture("/assets/minecraft/textures/gui/unknown_pack.png").bind();
         }
     }
 
     @Override
-	public void readZipFile()
-    {
-        try
-        {
-            zipFile = new ZipFile(file);
+    public void readZipFile() {
+        try {
+            this.zipFile = new ZipFile(this.file);
+        } catch (Exception ignored) {
         }
-        catch(Exception ignored) { }
     }
 
     @Override
-	public void closeTexturePackFile()
-    {
-        try
-        {
-            zipFile.close();
+    public void closeTexturePackFile() {
+        try {
+            this.zipFile.close();
+        } catch (Exception ignored) {
         }
-        catch(Exception ignored) { }
-        zipFile = null;
+        this.zipFile = null;
     }
 
     @Override
-	public InputStream getResourceAsStream(String path)
-    {
-    	return getResourceAsStream(path, true);
-	}
-	private InputStream getResourceAsStream(String path, boolean firstCall)
-	{
-		if (firstCall && Holidays.getCurrentThemedHoliday() != null && Minecraft.getMinecraft().gameSettings.enableHolidayTextures.value) {
-			assert Holidays.getCurrentThemedHoliday().getCustomResourcesSubPath() != null : "Current themed holiday must have a theme!";
-			String holidayPath = ("/holidays/" + Holidays.getCurrentThemedHoliday().getCustomResourcesSubPath() + "/" + path).replace("//", "/");
-			InputStream holidayStream = getResourceAsStream(holidayPath, false);
-			if (holidayStream != null) return holidayStream;
-		}
+    public InputStream getResourceAsStream(String path) {
+        return getResourceAsStream(path, true);
+    }
 
-		if (file.isFile())
-		{
-			String zipEntryPath = path;
-			if (path.startsWith("/")) zipEntryPath = path.substring(1);
-			try
-			{
-				java.util.zip.ZipEntry zipentry = zipFile.getEntry(zipEntryPath);
-				if(zipentry != null)
-				{
-					return zipFile.getInputStream(zipentry);
-				}
-			}
-			catch(Exception ignored)
-			{
-				return null;
-			}
-		}
-		else
-		{
-			try
-			{
-				File file = new File(this.file, path);
-				if (file.exists())
-				{
-					return Files.newInputStream(file.toPath());
-				}
-			}
-			catch (Exception ignored)
-			{
-				return null;
-			}
-		}
+    private InputStream getResourceAsStream(String path, boolean firstCall) {
+        if (firstCall && Holidays.getCurrentThemedHoliday() != null && GameSettings.ENABLE_HOLIDAY_TEXTURES.value) {
+            assert Holidays.getCurrentThemedHoliday().getCustomResourcesSubPath() != null : "Current themed holiday must have a theme!";
+            String holidayPath = ("/holidays/" + Holidays.getCurrentThemedHoliday().getCustomResourcesSubPath() + "/" + path).replace("//", "/");
+            InputStream holidayStream = getResourceAsStream(holidayPath, false);
+            if (holidayStream != null) return holidayStream;
+        }
 
-		return null;
-	}
+        if (this.file.isFile()) {
+            String zipEntryPath = path;
+            if (path.startsWith("/")) zipEntryPath = path.substring(1);
+            try {
+                java.util.zip.ZipEntry zipentry = this.zipFile.getEntry(zipEntryPath);
+                if (zipentry != null) {
+                    return this.zipFile.getInputStream(zipentry);
+                }
+            } catch (Exception ignored) {
+                return null;
+            }
+        } else {
+            try {
+                File file = new File(this.file, path);
+                if (file.exists()) {
+                    return Files.newInputStream(file.toPath());
+                }
+            } catch (Exception ignored) {
+                return null;
+            }
+        }
 
-	@Override
-	protected String[] getFilesInDirectory(String directory)
-	{
-		if (!directory.endsWith("/")) directory = directory + "/";
-		if (file.isFile())
-		{
-			ZipEntry dirEntry = zipFile.getEntry(directory);
-			if (dirEntry != null)
-			{
-				if (dirEntry.isDirectory())
-				{
-					List<String> files = new ArrayList<>();
-					Enumeration<? extends ZipEntry> e = zipFile.entries();
-					while (e.hasMoreElements())
-					{
-						ZipEntry entry = e.nextElement();
-						if (entry.getName().startsWith(directory))
-						{
-							files.add(entry.getName());
-						}
-					}
+        return null;
+    }
 
-					return files.toArray(new String[0]);
-				}
-				else return new String[] { directory };
-			}
-			else return super.getFilesInDirectory(directory);
-		}
-		else
-		{
-			File file = new File(this.file, directory);
-			if (file.exists())
-			{
-				if (file.isDirectory())
-				{
-					File[] files = file.listFiles();
-					if (files != null)
-					{
-						String[] fileStrings = new String[files.length];
-						for (int i = 0; i < files.length; i++)
-						{
-							fileStrings[i] = directory + files[i].getName();
-						}
+    @Override
+    protected String[] getFilesInDirectory(String directory) {
+        if (!directory.endsWith("/")) directory = directory + "/";
+        if (this.file.isFile()) {
+            ZipEntry dirEntry = this.zipFile.getEntry(directory);
+            if (dirEntry != null) {
+                if (dirEntry.isDirectory()) {
+                    List<String> files = new ArrayList<>();
+                    Enumeration<? extends ZipEntry> e = this.zipFile.entries();
+                    while (e.hasMoreElements()) {
+                        ZipEntry entry = e.nextElement();
+                        if (entry.getName().startsWith(directory)) {
+                            files.add(entry.getName());
+                        }
+                    }
 
-						return fileStrings;
-					}
-					else
-					{
-						return new String[0];
-					}
-				}
-				else return new String[] { directory };
-			}
-			else return super.getFilesInDirectory(directory);
-		}
-	}
+                    return files.toArray(new String[0]);
+                } else return new String[]{directory};
+            } else return super.getFilesInDirectory(directory);
+        } else {
+            File file = new File(this.file, directory);
+            if (file.exists()) {
+                if (file.isDirectory()) {
+                    File[] files = file.listFiles();
+                    if (files != null) {
+                        String[] fileStrings = new String[files.length];
+                        for (int i = 0; i < files.length; i++) {
+                            fileStrings[i] = directory + files[i].getName();
+                        }
 
-	@Override
-	public boolean hasFile(String file)
-	{
-		if(this.file.isFile())
-		{
-			boolean h = false;
-			try (ZipFile zipfile = new ZipFile(this.file))
-			{
-				h = zipfile.getEntry(file.substring(1)) != null;
-			}
-			catch (IOException ignored)
-			{
-			}
-			return h;
-		}
-		else
-		{
-			return new File(this.file, file).exists();
-		}
-	}
+                        return fileStrings;
+                    } else {
+                        return new String[0];
+                    }
+                } else return new String[]{directory};
+            } else return super.getFilesInDirectory(directory);
+        }
+    }
+
+    @Override
+    public boolean hasFile(String file) {
+        if (this.file.isFile()) {
+            boolean h = false;
+            try (ZipFile zipfile = new ZipFile(this.file)) {
+                h = zipfile.getEntry(file.substring(1)) != null;
+            } catch (IOException ignored) {
+            }
+            return h;
+        } else {
+            return new File(this.file, file).exists();
+        }
+    }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePackDefault.java b/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePackDefault.java
index a02869ba9..0ac96cf24 100644
--- a/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePackDefault.java
+++ b/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePackDefault.java
@@ -9,65 +9,54 @@ import javax.imageio.ImageIO;
 import com.mojang.logging.LogUtils;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.holiday.Holidays;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.texture.TextureBuffered;
 import org.slf4j.Logger;
 
-public class TexturePackDefault extends TexturePack
-{
+public class TexturePackDefault extends TexturePack {
     private static final Logger LOGGER = LogUtils.getLogger();
     private TextureBuffered texturePackThumbnailTexture;
     private BufferedImage texturePackThumbnail;
 
-    public TexturePackDefault()
-    {
-        texturePackThumbnailTexture = null;
-        fileName = "Default";
-        manifest = new Manifest(null, TexturePackDefault.class.getResourceAsStream("/manifest.json"));
-        try
-        {
-            texturePackThumbnail = ImageIO.read(TexturePackDefault.class.getResource("/pack.png"));
-        }
-        catch(IOException e)
-        {
-            LOGGER.error("Failed to read thumbnail for '{}'!", packId, e);
+    public TexturePackDefault() {
+        this.texturePackThumbnailTexture = null;
+        this.fileName = "Default";
+        this.manifest = new Manifest(null, TexturePackDefault.class.getResourceAsStream("/manifest.json"));
+        try {
+            this.texturePackThumbnail = ImageIO.read(TexturePackDefault.class.getResource("/pack.png"));
+        } catch (IOException e) {
+            LOGGER.error("Failed to read thumbnail for '{}'!", this.packId, e);
         }
     }
 
     @Override
-    public void disposeOfTexturePack(Minecraft minecraft)
-    {
-        if(texturePackThumbnail != null) {
-            texturePackThumbnailTexture.delete();
-            texturePackThumbnailTexture = null;
+    public void disposeOfTexturePack(Minecraft minecraft) {
+        if (this.texturePackThumbnail != null) {
+            this.texturePackThumbnailTexture.delete();
+            this.texturePackThumbnailTexture = null;
         }
     }
 
     @Override
-    public void bindThumbnailTexture(Minecraft minecraft)
-    {
-        if(texturePackThumbnail != null && texturePackThumbnailTexture == null)
-        {
-            texturePackThumbnailTexture = minecraft.textureManager.loadBufferedTexture(texturePackThumbnail);
-        }
-        if(texturePackThumbnail != null)
-        {
-            minecraft.textureManager.bindTexture(texturePackThumbnailTexture);
+    public void bindThumbnailTexture(Minecraft minecraft) {
+        if (this.texturePackThumbnail != null && this.texturePackThumbnailTexture == null) {
+            this.texturePackThumbnailTexture = minecraft.textureManager.loadBufferedTexture(this.texturePackThumbnail);
         }
-        else
-        {
+        if (this.texturePackThumbnail != null) {
+            minecraft.textureManager.bindTexture(this.texturePackThumbnailTexture);
+        } else {
             minecraft.textureManager.loadTexture("/assets/minecraft/textures/gui/unknown_pack.png").bind();
         }
     }
 
     @Override
     public boolean hasFile(String file) {
-		try
-        {
-			InputStream stream = TexturePackDefault.class.getResourceAsStream(file);
+        try {
+            InputStream stream = TexturePackDefault.class.getResourceAsStream(file);
             if (stream != null) {
                 stream.close();
                 return true;
-            } else if (Minecraft.getMinecraft().gameSettings.enableHolidayTextures.value && Holidays.getCurrentThemedHoliday() != null) {
+            } else if (GameSettings.ENABLE_HOLIDAY_TEXTURES.value && Holidays.getCurrentThemedHoliday() != null) {
                 assert Holidays.getCurrentThemedHoliday().getCustomResourcesSubPath() != null : "Current themed holiday must have a theme!";
                 String holidayPath = ("/holidays/" + Holidays.getCurrentThemedHoliday().getCustomResourcesSubPath() + "/" + file).replace("//", "/");
                 InputStream holidayStream = TexturePack.class.getResourceAsStream(holidayPath);
@@ -77,10 +66,8 @@ public class TexturePackDefault extends TexturePack
                 }
             }
             return false;
-		}
-        catch (Exception e)
-        {
-			return false;
-		}
-	}
+        } catch (Exception e) {
+            return false;
+        }
+    }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePackList.java b/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePackList.java
index 5e70813f2..16420a84f 100644
--- a/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePackList.java
+++ b/game/client/src/main/java/net/minecraft/client/render/texturepack/TexturePackList.java
@@ -4,6 +4,7 @@ import com.mojang.logging.LogUtils;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.TooltipElement;
 import net.minecraft.client.gui.keyboard.KeyboardLayout;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.EntityRendererDispatcher;
 import net.minecraft.client.render.TileEntityRenderDispatcher;
 import net.minecraft.client.render.block.color.BlockColorDispatcher;
@@ -49,62 +50,62 @@ public class TexturePackList
 	}
 
 	public void shiftPack(TexturePack pack, int shiftAmount){
-		if (!selectedPacks.contains(pack)) return;
+		if (!this.selectedPacks.contains(pack)) return;
 		if (shiftAmount == 0) return;
-		int currentIndex = selectedPacks.indexOf(pack);
+		int currentIndex = this.selectedPacks.indexOf(pack);
 		int newIndex = currentIndex + shiftAmount;
 		if (newIndex < 0){
 			newIndex = 0;
 		}
-		if (newIndex >= selectedPacks.size()){
-			newIndex = selectedPacks.size() - 1;
+		if (newIndex >= this.selectedPacks.size()){
+			newIndex = this.selectedPacks.size() - 1;
 		}
-		selectedPacks.remove(pack);
-		selectedPacks.add(newIndex, pack);
+        this.selectedPacks.remove(pack);
+        this.selectedPacks.add(newIndex, pack);
 		savePacksToSettings();
-		isDirty = true;
+        this.isDirty = true;
 	}
     public void setTexturePack(TexturePack newPack)
     {
-		if (!selectedPacks.contains(newPack)){
-			selectedPacks.add(newPack);
+		if (!this.selectedPacks.contains(newPack)){
+            this.selectedPacks.add(newPack);
 			newPack.readZipFile();
 			savePacksToSettings();
-			isDirty = true;
+            this.isDirty = true;
 		}
     }
 	public void savePacksToSettings(){
-		mc.gameSettings.skin.value = packSaveString();
-		mc.gameSettings.saveOptions();
+		GameSettings.SKIN.value = packSaveString();
+		GameSettings.saveOptions();
 	}
 	public String packSaveString(){
 		StringBuilder builder = new StringBuilder();
-		for (TexturePack pack : selectedPacks){
-			if (pack == defaultTexturePack) continue;
+		for (TexturePack pack : this.selectedPacks){
+			if (pack == this.defaultTexturePack) continue;
 			builder.append(pack.fileName).append(SEPERATOR);
 		}
 		return builder.toString();
 	}
 	public void unsetTexturePack(TexturePack pack){
 		pack.closeTexturePackFile();
-		selectedPacks.remove(pack);
+        this.selectedPacks.remove(pack);
 		savePacksToSettings();
-		isDirty = true;
+        this.isDirty = true;
 	}
 	public void refreshIfReady(){
-		if (isDirty){
-			isDirty = false;
+		if (this.isDirty){
+            this.isDirty = false;
 			refresh();
 		}
 	}
 
 	public void refresh() {
-		mc.textureManager.refreshTexturesAndDisplayErrors();
-		mc.renderGlobal.allChanged();
-		if (mc.currentScreen != null) {
-			mc.currentScreen.updateFont();
+        this.mc.textureManager.refreshTexturesAndDisplayErrors();
+        this.mc.renderGlobal.allChanged();
+		if (this.mc.currentScreen != null) {
+            this.mc.currentScreen.updateFont();
 		}
-		mc.textureManager.updateDynamicTextures(false);
+        this.mc.textureManager.updateDynamicTextures(false);
 		SoundRepository.reload();
 		BlockColorDispatcher.getInstance().reload();
 		BlockModelDispatcher.getInstance().reload();
@@ -121,12 +122,12 @@ public class TexturePackList
 
 		boolean update = false;
 
-		if(texturePackDir.exists() && texturePackDir.isDirectory()) {
-			File[] filesArr = texturePackDir.listFiles();
+		if(this.texturePackDir.exists() && this.texturePackDir.isDirectory()) {
+			File[] filesArr = this.texturePackDir.listFiles();
 
 			if(filesArr != null) {
                 List<File> fileList = new ArrayList<>(Arrays.asList(filesArr));
-				if (mc.gameSettings.enableDevResourceLoading.value) { // Load project resources as an available texture pack
+				if (GameSettings.ENABLE_DEV_RESOURCE_LOADING.value) { // Load project resources as an available texture pack
 					File resources = new File("./src/main/resources");
 					fileList.add(resources);
 
@@ -143,18 +144,18 @@ public class TexturePackList
 					}
 					String id = getTexturePackID(file);
 					try {
-						if(!texturePackIDs.containsKey(id)) {
+						if(!this.texturePackIDs.containsKey(id)) {
 							TexturePackCustom pack = new TexturePackCustom(file);
 							pack.packId = id;
 							pack.readZipFile();
 							pack.readTexturePackManifest();
 
-							texturePackIDs.put(id, pack);
+                            this.texturePackIDs.put(id, pack);
 							pack.closeTexturePackFile();
 							update = true;
 						}
 
-						TexturePack pack = texturePackIDs.get(id);
+						TexturePack pack = this.texturePackIDs.get(id);
 						currentTexturePacks.add(pack);
 					}catch (IOException e) {
                         LOGGER.error("Failed to make texturepack for file '{}'!", file.getPath(), e);
@@ -170,18 +171,18 @@ public class TexturePackList
 		}
 
 		for(TexturePack texturePack : previousTexturePacks) {
-			texturePack.disposeOfTexturePack(mc);
-			texturePackIDs.remove(texturePack.packId);
+			texturePack.disposeOfTexturePack(this.mc);
+            this.texturePackIDs.remove(texturePack.packId);
 		}
 
 		this.availableTexturePacks = currentTexturePacks;
 
-		String[] packStrings = mc.gameSettings.skin.value.split(SEPERATOR);
+		String[] packStrings = GameSettings.SKIN.value.split(SEPERATOR);
 		for (String string : packStrings){
-			for (TexturePack pack : availableTexturePacks){
-				if (string.equals(pack.fileName) && !selectedPacks.contains(pack)){
+			for (TexturePack pack : this.availableTexturePacks){
+				if (string.equals(pack.fileName) && !this.selectedPacks.contains(pack)){
 					pack.readZipFile();
-					selectedPacks.add(pack);
+                    this.selectedPacks.add(pack);
 				}
 			}
 		}
@@ -213,32 +214,32 @@ public class TexturePackList
 
     public List<TexturePack> availableTexturePacks()
     {
-        return new ArrayList<>(availableTexturePacks);
+        return new ArrayList<>(this.availableTexturePacks);
     }
     public List<TexturePack> selectedTexturePacks()
     {
-        return new ArrayList<>(selectedPacks);
+        return new ArrayList<>(this.selectedPacks);
     }
 
     public TexturePack getDefaultTexturePack()
     {
-        return defaultTexturePack;
+        return this.defaultTexturePack;
     }
 	public InputStream getResourceAsStream(String s){
 		return getResourceAsStream(s, true);
 	}
 	private InputStream getResourceAsStream(String s, boolean firstCall) {
 		InputStream stream;
-		for (int i = selectedPacks.size() - 1; i >= 0; i--) {
-			TexturePack pack = selectedPacks.get(i);
+		for (int i = this.selectedPacks.size() - 1; i >= 0; i--) {
+			TexturePack pack = this.selectedPacks.get(i);
 			stream = pack.getResourceAsStream(s);
 			if (stream != null) return stream;
 		}
-		return defaultTexturePack.getResourceAsStream(s);
+		return this.defaultTexturePack.getResourceAsStream(s);
 	}
 	public TexturePack getHighestPriorityPack(){
-		if (selectedPacks.isEmpty()) return defaultTexturePack;
-		return selectedPacks.get(selectedPacks.size()-1);
+		if (this.selectedPacks.isEmpty()) return this.defaultTexturePack;
+		return this.selectedPacks.get(this.selectedPacks.size()-1);
 	}
 
 	public boolean anyHasFile(String path) {
@@ -252,14 +253,14 @@ public class TexturePackList
 		return getHighestPriorityTexturePackWithFile(path, true);
 	}
 	private @Nullable TexturePack getHighestPriorityTexturePackWithFile(String path, boolean firstCall) {
-		for(int i = selectedPacks.size() - 1; i >= 0; i--) {
-			TexturePack texturePack = selectedPacks.get(i);
+		for(int i = this.selectedPacks.size() - 1; i >= 0; i--) {
+			TexturePack texturePack = this.selectedPacks.get(i);
 			if(texturePack.hasFile(path)) {
 				return texturePack;
 			}
 		}
-		if(defaultTexturePack.hasFile(path)) {
-			return defaultTexturePack;
+		if(this.defaultTexturePack.hasFile(path)) {
+			return this.defaultTexturePack;
 		}
 		return null;
 	}
diff --git a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererJarButterfly.java b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererJarButterfly.java
index 6c5206ab9..c813ce39b 100644
--- a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererJarButterfly.java
+++ b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererJarButterfly.java
@@ -2,12 +2,17 @@ package net.minecraft.client.render.tileentity;
 
 import net.minecraft.client.render.entity.MobRendererButterfly;
 import net.minecraft.client.render.tessellator.TessellatorGeneral;
+import net.minecraft.core.block.BlockLogicJarButterfly;
 import net.minecraft.core.block.entity.TileEntityJarButterfly;
 import net.minecraft.core.util.helper.MathHelper;
 
 public class TileEntityRendererJarButterfly extends TileEntityRenderer<TileEntityJarButterfly>{
     @Override
     public void doRender(TessellatorGeneral tessellator, TileEntityJarButterfly tileEntity, double x, double y, double z, float partialTick) {
-        MobRendererButterfly.drawButterfly(tessellator, tileEntity.ticksRan, 0.70f, 0, x + 0.5, y - 0.125 + MathHelper.sin((tileEntity.ticksRan + partialTick)/20) * (0.0625), z + 0.5, partialTick, renderDispatcher.textureManager, "/assets/minecraft/textures/entity/butterfly/" + tileEntity.color.name + "/0_0.png");
+        int meta = tileEntity.getBlockMeta();
+        boolean hanging = (meta & BlockLogicJarButterfly.MASK_HANGING) != 0;
+        MobRendererButterfly.drawButterfly(tessellator, tileEntity.ticksRan, 0.70f, 0,
+            x + 0.5, y + (hanging ? 6/16f : 0) - 0.125 + MathHelper.sin((tileEntity.ticksRan + partialTick)/20) * (0.0625), z + 0.5,
+            partialTick, this.renderDispatcher.textureManager, "/assets/minecraft/textures/entity/butterfly/" + tileEntity.color.name + "/0_0.png");
     }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMeshGold.java b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMeshGold.java
index 209b75455..842d66d02 100644
--- a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMeshGold.java
+++ b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererMeshGold.java
@@ -1,5 +1,6 @@
 package net.minecraft.client.render.tileentity;
 
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.renderer.GLRenderer;
 import net.minecraft.core.block.entity.TileEntityMeshGold;
 
@@ -23,7 +24,7 @@ public class TileEntityRendererMeshGold extends TileEntityRenderer<TileEntityMes
 
 
         ItemModelDispatcher.getInstance().getDispatch(tileEntity.filterItem).renderItemEntity(tessellator, tileEntity.filterItem,
-            Minecraft.getMinecraft().gameSettings.items3D.value, 1, tileEntity.ticksRan, yaw,
+            GameSettings.ITEMS_3D.value, 1, tileEntity.ticksRan, yaw,
             Minecraft.getMinecraft().currentWorld.getLightmapCoord(new TilePos(tileEntity.x, tileEntity.y, tileEntity.z), 0), renderPartialTicks);
         GLRenderer.popFrame();
     }
diff --git a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererSign.java b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererSign.java
index 2b4620b52..73fac9b52 100644
--- a/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererSign.java
+++ b/game/client/src/main/java/net/minecraft/client/render/tileentity/TileEntityRendererSign.java
@@ -2,8 +2,9 @@ package net.minecraft.client.render.tileentity;
 
 import it.unimi.dsi.fastutil.ints.IntArrayList;
 import it.unimi.dsi.fastutil.ints.IntList;
-import net.minecraft.client.GLAllocation;
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
+import net.minecraft.client.option.enums.TextOutlineQuality;
 import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.camera.ICamera;
 import net.minecraft.client.render.font.FontRenderer;
@@ -23,7 +24,6 @@ import net.minecraft.core.enums.EnumSignPicture;
 import net.minecraft.core.util.helper.Color;
 import net.minecraft.core.util.helper.DyeColor;
 import net.minecraft.core.util.helper.MathHelper;
-import net.minecraft.core.world.World;
 import org.jetbrains.annotations.NotNull;
 import org.joml.Math;
 import org.joml.primitives.AABBd;
@@ -152,7 +152,7 @@ public class TileEntityRendererSign extends TileEntityRenderer<TileEntitySign> {
         }
         final int _x = 0;
         final int _y = -tileEntity.signText.length * 5;
-        if (tileEntity.isGlowing() && this.mc.gameSettings.fancyGraphics.value >= 1) {
+        if (tileEntity.isGlowing() && GameSettings.TEXT_OUTLINE_QUALITY.value == TextOutlineQuality.FANCY) {
             this.textMeshRenderer.render(sr, t, line1, line2, line3, line4, _x, _y, SF.setOutlined(SF.setColor(0, color)));
         } else {
             this.textMeshRenderer.render(sr, t, line1, line2, line3, line4, _x, _y, SF.setColor(0, color));
diff --git a/game/client/src/main/java/net/minecraft/client/render/window/GameWindow.java b/game/client/src/main/java/net/minecraft/client/render/window/GameWindow.java
index ade0cb6e0..c4a65237b 100644
--- a/game/client/src/main/java/net/minecraft/client/render/window/GameWindow.java
+++ b/game/client/src/main/java/net/minecraft/client/render/window/GameWindow.java
@@ -1,7 +1,6 @@
 package net.minecraft.client.render.window;
 
 import net.minecraft.client.Minecraft;
-import net.minecraft.core.UnexpectedThrowable;
 
 public interface GameWindow {
 	
@@ -10,8 +9,9 @@ public interface GameWindow {
 	void toggleFullscreen();
 	
 	void updateWindowState();
-	
-	void displayCrashReport(UnexpectedThrowable unexpectedThrowable, int cause);
+
+	// Does not work with headless mode set to false
+//	void displayCrashReport(UnexpectedThrowable unexpectedThrowable, int cause);
 	
 	int getFrequency();
 	
diff --git a/game/client/src/main/java/net/minecraft/client/render/window/GameWindowGLFW.java b/game/client/src/main/java/net/minecraft/client/render/window/GameWindowGLFW.java
index e973bd7e1..ce70ed33c 100644
--- a/game/client/src/main/java/net/minecraft/client/render/window/GameWindowGLFW.java
+++ b/game/client/src/main/java/net/minecraft/client/render/window/GameWindowGLFW.java
@@ -1,25 +1,12 @@
 package net.minecraft.client.render.window;
 
-import static org.lwjgl.glfw.GLFW.*;
-import static org.lwjgl.system.MemoryUtil.NULL;
-
-import java.awt.*;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.nio.IntBuffer;
-import java.util.Objects;
-
-import javax.swing.JFrame;
-
-import com.mojang.logging.CategorizedLogger;
+import com.github.zarzelcow.legacylwjgl3.implementation.glfw.GLFWKeyboardImplementation;
+import com.github.zarzelcow.legacylwjgl3.implementation.glfw.GLFWMouseImplementation;
+import com.github.zarzelcow.legacylwjgl3.implementation.input.CombinedInputImplementation;
+import com.github.zarzelcow.legacylwjgl3.implementation.input.InputImplementation;
 import com.mojang.logging.LogUtils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.OpenGLHelper;
 import net.minecraft.client.util.debug.GLFWLoggerCallback;
 import net.minecraft.client.util.debug.OpenGLLoggerCallback;
@@ -37,21 +24,72 @@ import org.lwjgl.glfw.GLFWImage;
 import org.lwjgl.glfw.GLFWVidMode;
 import org.lwjgl.input.Keyboard;
 import org.lwjgl.input.Mouse;
-import org.lwjgl.opengl.*;
-
-import com.github.zarzelcow.legacylwjgl3.implementation.glfw.GLFWKeyboardImplementation;
-import com.github.zarzelcow.legacylwjgl3.implementation.glfw.GLFWMouseImplementation;
-import com.github.zarzelcow.legacylwjgl3.implementation.input.CombinedInputImplementation;
-import com.github.zarzelcow.legacylwjgl3.implementation.input.InputImplementation;
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.render.PanelCrashReport;
-import net.minecraft.core.UnexpectedThrowable;
+import org.lwjgl.opengl.Display;
+import org.lwjgl.opengl.GL;
+import org.lwjgl.opengl.GL41;
+import org.lwjgl.opengl.GL43;
+import org.lwjgl.opengl.GLCapabilities;
+import org.lwjgl.opengl.GLDebugMessageCallback;
 import org.lwjgl.stb.STBImage;
 import org.lwjgl.system.MemoryStack;
 import org.lwjgl.system.MemoryUtil;
 import org.slf4j.Logger;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import static org.lwjgl.glfw.GLFW.GLFW_ARROW_CURSOR;
+import static org.lwjgl.glfw.GLFW.GLFW_AUTO_ICONIFY;
+import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MAJOR;
+import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MINOR;
+import static org.lwjgl.glfw.GLFW.GLFW_CROSSHAIR_CURSOR;
+import static org.lwjgl.glfw.GLFW.GLFW_DECORATED;
+import static org.lwjgl.glfw.GLFW.GLFW_HAND_CURSOR;
+import static org.lwjgl.glfw.GLFW.GLFW_HRESIZE_CURSOR;
+import static org.lwjgl.glfw.GLFW.GLFW_IBEAM_CURSOR;
+import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_FORWARD_COMPAT;
+import static org.lwjgl.glfw.GLFW.GLFW_RESIZABLE;
+import static org.lwjgl.glfw.GLFW.GLFW_TRUE;
+import static org.lwjgl.glfw.GLFW.GLFW_VISIBLE;
+import static org.lwjgl.glfw.GLFW.GLFW_VRESIZE_CURSOR;
+import static org.lwjgl.glfw.GLFW.glfwCreateWindow;
+import static org.lwjgl.glfw.GLFW.glfwGetError;
+import static org.lwjgl.glfw.GLFW.glfwGetFramebufferSize;
+import static org.lwjgl.glfw.GLFW.glfwGetMonitorPos;
+import static org.lwjgl.glfw.GLFW.glfwGetMonitors;
+import static org.lwjgl.glfw.GLFW.glfwGetPrimaryMonitor;
+import static org.lwjgl.glfw.GLFW.glfwGetVideoMode;
+import static org.lwjgl.glfw.GLFW.glfwGetWindowMonitor;
+import static org.lwjgl.glfw.GLFW.glfwGetWindowPos;
+import static org.lwjgl.glfw.GLFW.glfwGetWindowSize;
+import static org.lwjgl.glfw.GLFW.glfwHideWindow;
+import static org.lwjgl.glfw.GLFW.glfwInit;
+import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent;
+import static org.lwjgl.glfw.GLFW.glfwPollEvents;
+import static org.lwjgl.glfw.GLFW.glfwSetFramebufferSizeCallback;
+import static org.lwjgl.glfw.GLFW.glfwSetWindowAttrib;
+import static org.lwjgl.glfw.GLFW.glfwSetWindowFocusCallback;
+import static org.lwjgl.glfw.GLFW.glfwSetWindowIcon;
+import static org.lwjgl.glfw.GLFW.glfwSetWindowMonitor;
+import static org.lwjgl.glfw.GLFW.glfwSetWindowPos;
+import static org.lwjgl.glfw.GLFW.glfwSetWindowSize;
+import static org.lwjgl.glfw.GLFW.glfwSetWindowSizeCallback;
+import static org.lwjgl.glfw.GLFW.glfwShowWindow;
+import static org.lwjgl.glfw.GLFW.glfwSwapBuffers;
+import static org.lwjgl.glfw.GLFW.glfwSwapInterval;
+import static org.lwjgl.glfw.GLFW.glfwWindowHint;
+import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose;
+import static org.lwjgl.system.MemoryUtil.NULL;
+
 public class GameWindowGLFW implements GameWindow {
     public static final Logger LOGGER = LogUtils.getLogger();
 
@@ -86,7 +124,7 @@ public class GameWindowGLFW implements GameWindow {
     public void init(Minecraft minecraft, int width, int height) {
         this.mc = minecraft;
 
-        boolean debug = (this.mc.gameSettings.developerMode.value || Version.BUILD_CHANNEL == BuildChannel.DEVELOPMENT || Global.DEBUG_MODE);
+        boolean debug = (GameSettings.DEVELOPER_MODE.value || Version.BUILD_CHANNEL == BuildChannel.DEVELOPMENT || Global.DEBUG_MODE);
 
         LOGGER.info("Initializing GLFW...");
         if (debug) {
@@ -228,7 +266,7 @@ public class GameWindowGLFW implements GameWindow {
         }
 
         // Set Vsync
-        setVsync(this.mc.gameSettings.enableVsync.value);
+        setVsync(GameSettings.ENABLE_VSYNC.value);
     }
 
     @Override
@@ -278,7 +316,7 @@ public class GameWindowGLFW implements GameWindow {
 
     @Override
     public void toggleFullscreen() {
-        this.mc.gameSettings.fullscreen.value = !this.mc.gameSettings.fullscreen.value;
+        GameSettings.FULLSCREEN.value = !GameSettings.FULLSCREEN.value;
 
         updateWindowState();
     }
@@ -302,8 +340,8 @@ public class GameWindowGLFW implements GameWindow {
             }
         }
 
-        boolean fullscreen = this.mc.gameSettings.fullscreen.value;
-        boolean borderless = this.mc.gameSettings.borderlessFullscreen.value;
+        boolean fullscreen = GameSettings.FULLSCREEN.value;
+        boolean borderless = GameSettings.BORDERLESS_FULLSCREEN.value;
 
         glfwHideWindow(this.window);
 
@@ -357,19 +395,20 @@ public class GameWindowGLFW implements GameWindow {
         return new MonitorInfo(glfwGetPrimaryMonitor());
     }
 
-    @Override
-    public void displayCrashReport(UnexpectedThrowable unexpectedThrowable, int cause) {
-        JFrame frame = new JFrame();
-        Panel panel = new PanelCrashReport(this.mc, unexpectedThrowable, cause);
-
-        panel.setPreferredSize(new java.awt.Dimension(1280, 720));
-
-        frame.add(panel);
-        frame.pack();
-        frame.setLocationRelativeTo(null);
-        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
-        frame.setVisible(true);
-    }
+    // This does not work when headless mode is on
+//    @Override
+//    public void displayCrashReport(UnexpectedThrowable unexpectedThrowable, int cause) {
+//        JFrame frame = new JFrame();
+//        Panel panel = new PanelCrashReport(this.mc, unexpectedThrowable, cause);
+//
+//        panel.setPreferredSize(new java.awt.Dimension(1280, 720));
+//
+//        frame.add(panel);
+//        frame.pack();
+//        frame.setLocationRelativeTo(null);
+//        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+//        frame.setVisible(true);
+//    }
 
     @Override
     public int getFrequency() {
@@ -453,10 +492,13 @@ public class GameWindowGLFW implements GameWindow {
 
     @Override
     public void free() {
-        Callbacks.glfwFreeCallbacks(this.window);
-        if (this.glfwErrorCallback != null) this.glfwErrorCallback.free();
-        if (this.glDebugMessageCallback != null) this.glDebugMessageCallback.free();
-        this.stbiIconImages.forEach(STBImage::stbi_image_free);
+        if (this.window != NULL) {
+            Callbacks.glfwFreeCallbacks(this.window);
+            this.window = NULL;
+            if (this.glfwErrorCallback != null) this.glfwErrorCallback.free();
+            if (this.glDebugMessageCallback != null) this.glDebugMessageCallback.free();
+            this.stbiIconImages.forEach(STBImage::stbi_image_free);
+        }
     }
 
     public static class MonitorInfo {
diff --git a/game/client/src/main/java/net/minecraft/client/sound/SoundCategoryHelper.java b/game/client/src/main/java/net/minecraft/client/sound/SoundCategoryHelper.java
index f12b0a0da..7694bc9ce 100644
--- a/game/client/src/main/java/net/minecraft/client/sound/SoundCategoryHelper.java
+++ b/game/client/src/main/java/net/minecraft/client/sound/SoundCategoryHelper.java
@@ -4,39 +4,32 @@ import com.mojang.logging.LogUtils;
 import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.option.OptionVolume;
 import net.minecraft.core.sound.SoundCategory;
+import org.jetbrains.annotations.NotNull;
 import org.slf4j.Logger;
 
 import java.lang.reflect.Field;
 import java.util.HashMap;
 
-public class SoundCategoryHelper
-{
+public class SoundCategoryHelper {
     private static final Logger LOGGER = LogUtils.getLogger();
     private static final HashMap<SoundCategory, Field> VOLUME_FIELDS = new HashMap<>();
 
-    static
-    {
-        try
-        {
-            VOLUME_FIELDS.put(SoundCategory.MUSIC, GameSettings.class.getDeclaredField("musicVolume"));
-            VOLUME_FIELDS.put(SoundCategory.WORLD_SOUNDS, GameSettings.class.getDeclaredField("worldSoundsVolume"));
-            VOLUME_FIELDS.put(SoundCategory.WEATHER_SOUNDS, GameSettings.class.getDeclaredField("weatherSoundsVolume"));
-            VOLUME_FIELDS.put(SoundCategory.ENTITY_SOUNDS, GameSettings.class.getDeclaredField("entitySoundsVolume"));
-            VOLUME_FIELDS.put(SoundCategory.CAVE_SOUNDS, GameSettings.class.getDeclaredField("caveSoundsVolume"));
-            VOLUME_FIELDS.put(SoundCategory.GUI_SOUNDS, GameSettings.class.getDeclaredField("guiSoundsVolume"));
-        }
-        catch (NoSuchFieldException e)
-        {
+    static {
+        try {
+            VOLUME_FIELDS.put(SoundCategory.MUSIC, GameSettings.class.getDeclaredField("MUSIC_VOLUME"));
+            VOLUME_FIELDS.put(SoundCategory.WORLD_SOUNDS, GameSettings.class.getDeclaredField("WORLD_SOUNDS_VOLUME"));
+            VOLUME_FIELDS.put(SoundCategory.WEATHER_SOUNDS, GameSettings.class.getDeclaredField("WEATHER_SOUNDS_VOLUME"));
+            VOLUME_FIELDS.put(SoundCategory.ENTITY_SOUNDS, GameSettings.class.getDeclaredField("ENTITY_SOUNDS_VOLUME"));
+            VOLUME_FIELDS.put(SoundCategory.CAVE_SOUNDS, GameSettings.class.getDeclaredField("CAVE_SOUNDS_VOLUME"));
+            VOLUME_FIELDS.put(SoundCategory.GUI_SOUNDS, GameSettings.class.getDeclaredField("GUI_SOUNDS_VOLUME"));
+        } catch (NoSuchFieldException e) {
             throw new RuntimeException(e);
         }
     }
 
-    public static boolean isAnyEnabled(GameSettings gameSettings)
-    {
-        for (SoundCategory category : SoundCategory.values())
-        {
-            if (getEffectiveVolume(category, gameSettings) > 0F)
-            {
+    public static boolean isAnyEnabled() {
+        for (SoundCategory category : SoundCategory.values()) {
+            if (getEffectiveVolume(category) > 0F) {
                 return true;
             }
         }
@@ -44,51 +37,39 @@ public class SoundCategoryHelper
         return false;
     }
 
-    public static float getVolume(SoundCategory category, GameSettings gameSettings)
-    {
+    public static float getVolume(SoundCategory category) {
         Field field = VOLUME_FIELDS.get(category);
         if (field == null) return 0.0f;
 
-        try
-        {
-            return ((OptionVolume) field.get(gameSettings)).value;
-        }
-        catch (Exception e)
-        {
+        try {
+            return ((OptionVolume) field.get(null)).value;
+        } catch (Exception e) {
             LOGGER.error("Failed to get volume for category '{}'!", field.getName(), e);
             return 0.0f;
         }
     }
 
-    public static float getEffectiveVolume(SoundCategory category, GameSettings gameSettings)
-    {
+    public static float getEffectiveVolume(@NotNull SoundCategory category) {
         Field field = VOLUME_FIELDS.get(category);
         if (field == null) return 0.0f;
 
-        try
-        {
-            float value = ((OptionVolume) field.get(gameSettings)).value;
-            return value * gameSettings.masterVolume.value;
-        }
-        catch (Exception e)
-        {
+        try {
+            float value = ((OptionVolume) field.get(null)).value;
+            return value * GameSettings.MASTER_VOLUME.value;
+        } catch (Exception e) {
             LOGGER.error("Failed to get effective volume for category '{}'!", field.getName(), e);
             return 0.0f;
         }
     }
 
-    public static void setVolume(SoundCategory category, GameSettings gameSettings, float value)
-    {
+    public static void setVolume(SoundCategory category, float value) {
         Field field = VOLUME_FIELDS.get(category);
         if (field == null) return;
 
-        try
-        {
-            OptionVolume option = (OptionVolume) field.get(gameSettings);
+        try {
+            OptionVolume option = (OptionVolume) field.get(null);
             option.value = value;
-        }
-        catch (Exception e)
-        {
+        } catch (Exception e) {
             LOGGER.error("Failed to set volume for category '{}'!", field.getName(), e);
         }
     }
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 1fae690ad..3170cea2a 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
@@ -24,14 +24,13 @@ public class SoundEngine
 {
 	private static final Logger LOGGER = LogUtils.getLogger();
 	private static @Nullable SoundSystem soundSystem;
-	private static Lock lock = new ReentrantLock();
+	private static final 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 @Nullable GameSettings options;
 	private final Random random;
 	private Minecraft mc;
 	public int ticksBeforeMusic;
@@ -43,7 +42,7 @@ public class SoundEngine
     }
 
 	public void resetMusicTicks() {
-		this.ticksBeforeMusic = this.options.musicFrequency.value.interval == 0 ? 0 : this.random.nextInt(this.options.musicFrequency.value.interval);
+		this.ticksBeforeMusic = GameSettings.MUSIC_FREQUENCY.value.interval == 0 ? 0 : this.random.nextInt(GameSettings.MUSIC_FREQUENCY.value.interval);
 	}
 
 	public void destroy() {
@@ -68,7 +67,7 @@ public class SoundEngine
 			if (this.muted) {
 				soundSystem.setVolume(BG_MUSIC, 0.0f);
 			} else {
-				soundSystem.setVolume(BG_MUSIC, SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC, this.options));
+				soundSystem.setVolume(BG_MUSIC, SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC));
 			}
 		} finally {
 			lock.unlock();
@@ -101,12 +100,11 @@ public class SoundEngine
 		}
     }
 
-    public void init(final GameSettings gamesettings) {
+    public void init() {
 		try {
 			lock.lock();
-			this.options = gamesettings;
 			this.resetMusicTicks();
-			if (!isLoaded() && SoundCategoryHelper.isAnyEnabled(gamesettings)) {
+			if (!isLoaded() && SoundCategoryHelper.isAnyEnabled()) {
 				loadLibrary();
 			}
 			this.mc = Minecraft.getMinecraft();
@@ -122,10 +120,10 @@ public class SoundEngine
 				loadLibrary();
 			}
 			if (soundSystem != null && loaded) {
-				if (SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC, this.options) == 0.0F) {
+				if (SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC) == 0.0F) {
 					soundSystem.stop(BG_MUSIC);
 				} else {
-					soundSystem.setVolume(BG_MUSIC, SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC, this.options));
+					soundSystem.setVolume(BG_MUSIC, SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC));
 				}
 			}
 		} finally {
@@ -136,7 +134,7 @@ public class SoundEngine
 	public void playTitleScreenMusic() {
 		try {
 			lock.lock();
-			if (!isLoaded() || SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC, this.options) == 0.0F) {
+			if (!isLoaded() || SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC) == 0.0F) {
 				return;
 			}
 
@@ -150,7 +148,7 @@ public class SoundEngine
 				if (entry != null) {
 					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.setVolume(BG_MUSIC, SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC) * entry.volume);
 					soundSystem.play(BG_MUSIC);
 				}
 			}
@@ -164,7 +162,7 @@ public class SoundEngine
     public void tick() {
 		try {
 			lock.lock();
-			if (!isLoaded() || SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC, this.options) == 0.0F) {
+			if (!isLoaded() || SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC) == 0.0F) {
 				return;
 			}
 
@@ -185,13 +183,13 @@ public class SoundEngine
 				final SoundEntry entry = event.getRandomEntry();
 				if (entry != null) {
 					this.resetMusicTicks();
-					this.ticksBeforeMusic += this.options.musicFrequency.value.interval;
+					this.ticksBeforeMusic += GameSettings.MUSIC_FREQUENCY.value.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.setVolume(BG_MUSIC, SoundCategoryHelper.getEffectiveVolume(SoundCategory.MUSIC) * entry.volume);
 					soundSystem.play(BG_MUSIC);
 
-					if (this.options.musicToasts.value && entry.title != null) {
+					if (GameSettings.MUSIC_TOASTS.value && entry.title != null) {
 						mc.guiToasts.addToast(new MusicToast(entry.title, entry.author));
 					}
 				}
@@ -264,7 +262,7 @@ public class SoundEngine
 							}
 							volume *= 0.25F;
 							soundSystem.setPitch(soundID, pitch * entry.pitch);
-							soundSystem.setVolume(soundID, volume * SoundCategoryHelper.getEffectiveVolume(category, this.options) * entry.volume);
+							soundSystem.setVolume(soundID, volume * SoundCategoryHelper.getEffectiveVolume(category) * entry.volume);
 							soundSystem.play(soundID);
 						}
 					} else if (entry.type == SoundEntry.Type.EVENT) {
@@ -318,7 +316,7 @@ public class SoundEngine
 							}
 
 							soundSystem.setPitch(soundID, pitch * entry.pitch);
-							soundSystem.setVolume(soundID, volume * SoundCategoryHelper.getEffectiveVolume(category, this.options) * entry.volume);
+							soundSystem.setVolume(soundID, volume * SoundCategoryHelper.getEffectiveVolume(category) * entry.volume);
 							soundSystem.play(soundID);
 						}
 					} else if (entry.type == SoundEntry.Type.EVENT) {
@@ -364,7 +362,7 @@ public class SoundEngine
 					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.setVolume(STREAMING, volume * entry.volume * GameSettings.MASTER_VOLUME.value);
 						soundSystem.play(STREAMING);
 					}
 				} else if (entry.type == SoundEntry.Type.EVENT) {
@@ -396,9 +394,9 @@ public class SoundEngine
 				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);
+					volumeStore[i] = SoundCategoryHelper.getVolume(SoundCategory.values()[i]);
 				}
-				this.options.saveOptions();
+				GameSettings.saveOptions();
 				SoundSystemConfig.addLibrary(LibraryLWJGL3OpenAL.class);
 				SoundSystemConfig.setCodec("ogg", CodecJOrbis.class);
 				SoundSystemConfig.setCodec("mus", CodecMus.class);
@@ -406,9 +404,9 @@ public class SoundEngine
 				soundSystem = new SoundSystem();
 				for (int i = 0; i < SoundCategory.values().length; i++)
 				{
-					SoundCategoryHelper.setVolume(SoundCategory.values()[i], this.options, volumeStore[i]);
+					SoundCategoryHelper.setVolume(SoundCategory.values()[i], volumeStore[i]);
 				}
-				this.options.saveOptions();
+				GameSettings.saveOptions();
 			} catch (final Throwable throwable) {
 				LOGGER.error("Error linking with the LibraryJavaSound plug-in", throwable);
 			}
@@ -423,7 +421,7 @@ public class SoundEngine
 	}
 
 	private boolean canPlaySounds() {
-		return isLoaded() && !this.muted && SoundCategoryHelper.isAnyEnabled(this.options);
+		return isLoaded() && !this.muted && SoundCategoryHelper.isAnyEnabled();
 	}
 
 	public static @Nullable SoundSystem getSoundSystem(){
diff --git a/game/client/src/main/java/net/minecraft/client/util/debug/DebugRender.java b/game/client/src/main/java/net/minecraft/client/util/debug/DebugRender.java
index 61584af1b..eeaa04eca 100644
--- a/game/client/src/main/java/net/minecraft/client/util/debug/DebugRender.java
+++ b/game/client/src/main/java/net/minecraft/client/util/debug/DebugRender.java
@@ -1,5 +1,6 @@
 package net.minecraft.client.util.debug;
 
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.font.FontRenderer;
 import net.minecraft.client.render.renderer.BlendFactor;
 import net.minecraft.client.render.renderer.GLRenderer;
@@ -178,14 +179,13 @@ public class DebugRender {
         tessellator.setColorOpaque1i(0xFF0000);
         drawRectangle(tessellator, x, y - tickLagHeight, frametimes.length, 1);
 
-        Minecraft mc = Minecraft.getMinecraft();
-        if (mc.gameSettings.customFpsLimit.value > 0 || mc.gameSettings.enableVsync.value) {
+        if (GameSettings.CUSTOM_FPS_LIMIT.value > 0 || GameSettings.ENABLE_VSYNC.value) {
             tessellator.setColorOpaque1i(0x00FF00);
             int fps;
-            if (mc.gameSettings.enableVsync.value) {
-                fps = mc.gameWindow.getFrequency(); // Cap fps when minimized
+            if (GameSettings.ENABLE_VSYNC.value) {
+                fps = Minecraft.getMinecraft().gameWindow.getFrequency(); // Cap fps when minimized
             } else {
-                fps = mc.gameSettings.customFpsLimit.value;
+                fps = GameSettings.CUSTOM_FPS_LIMIT.value;
             }
 
             int frameLagHeight = (int) ((1000d / fps * 1000 * 1000) / scale);
diff --git a/game/client/src/main/java/net/minecraft/client/util/helper/ScreenshotHelper.java b/game/client/src/main/java/net/minecraft/client/util/helper/ScreenshotHelper.java
index 86d2ff837..de886090b 100644
--- a/game/client/src/main/java/net/minecraft/client/util/helper/ScreenshotHelper.java
+++ b/game/client/src/main/java/net/minecraft/client/util/helper/ScreenshotHelper.java
@@ -12,6 +12,7 @@ import java.io.File;
 import javax.imageio.ImageIO;
 
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.FrameBuffer;
 import net.minecraft.client.render.Renderer;
 import net.minecraft.client.render.texture.Texture;
@@ -50,7 +51,7 @@ public class ScreenshotHelper {
 	}
 	
 	private void takeScreenshot() throws Exception {
-        this.minecraft.gameSettings.FoV.value = 0.6056338f; //90 Degrees
+        GameSettings.FOV.value = 0.6056338f; //90 Degrees
         this.minecraft.thePlayer.yRot = 0.0f;
         this.minecraft.thePlayer.xRot = 0.0f;
         this.minecraft.thePlayer.yRotO = this.minecraft.thePlayer.yRot;
@@ -114,14 +115,14 @@ public class ScreenshotHelper {
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, this.depthtex.id(), 0);
 
-        this.fov = this.minecraft.gameSettings.FoV.get();
+        this.fov = GameSettings.FOV.get();
         this.yaw = this.minecraft.thePlayer.yRot;
         this.pitch = this.minecraft.thePlayer.xRot;
         this.renderer = this.minecraft.renderer;
         this.oldWidth = this.minecraft.gameWindow.getWidthPixels();
         this.oldHeight = this.minecraft.gameWindow.getHeightPixels();
-        this.immersiveMode = this.minecraft.gameSettings.immersiveMode.value;
-        this.minecraft.gameSettings.immersiveMode.value = 2;
+        this.immersiveMode = GameSettings.IMMERSIVE_MODE.value;
+        GameSettings.IMMERSIVE_MODE.value = 2;
 
 //		minecraft.renderer = new FallbackRenderer(minecraft);
 	}
@@ -133,11 +134,11 @@ public class ScreenshotHelper {
         this.colortex.delete();
         this.depthtex.delete();
 
-        this.minecraft.gameSettings.FoV.value = this.fov;
+        GameSettings.FOV.value = this.fov;
         this.minecraft.thePlayer.yRot = this.yaw;
         this.minecraft.thePlayer.xRot = this.pitch;
         this.minecraft.renderer = this.renderer;
-        this.minecraft.gameSettings.immersiveMode.value = this.immersiveMode;
+        GameSettings.IMMERSIVE_MODE.value = this.immersiveMode;
 	}
 	
 }
diff --git a/game/client/src/main/java/net/minecraft/client/world/WorldClient.java b/game/client/src/main/java/net/minecraft/client/world/WorldClient.java
index d87ce142e..bdf321612 100644
--- a/game/client/src/main/java/net/minecraft/client/world/WorldClient.java
+++ b/game/client/src/main/java/net/minecraft/client/world/WorldClient.java
@@ -1,6 +1,6 @@
 package net.minecraft.client.world;
 
-import net.minecraft.client.Minecraft;
+import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.camera.ICamera;
 import net.minecraft.client.render.colorizer.Colorizers;
@@ -11,6 +11,7 @@ import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.AuroraProvider;
 import net.minecraft.core.world.Dimension;
 import net.minecraft.core.world.World;
+import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.save.LevelData;
 import net.minecraft.core.world.save.LevelStorage;
@@ -22,14 +23,15 @@ import net.minecraft.core.world.weather.IPrecipitation;
 import net.minecraft.core.world.weather.WeatherManager;
 import net.minecraft.core.world.weather.Weathers;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.joml.Vector3f;
 import org.joml.Vector3fc;
 
 public class WorldClient extends World {
     public static final WorldClient EMPTY_WORLD = new WorldClient();
 
-    public WorldClient(LevelStorage saveHandler, String name, long seed, Dimension dimension, WorldType worldType) {
-        super(saveHandler, name, seed, dimension, worldType);
+    public WorldClient(LevelStorage saveHandler, String name, long seed, Dimension dimension, WorldType worldType, @Nullable Biome startingBiome) {
+        super(saveHandler, name, seed, dimension, worldType, startingBiome);
     }
 
     public WorldClient(World world, Dimension dimension) {
@@ -161,6 +163,6 @@ public class WorldClient extends World {
 
     @Override
     public int renderDistance() {
-        return Minecraft.getMinecraft().gameSettings.renderDistance.value;
+        return GameSettings.RENDER_DISTANCE.value;
     }
 }
diff --git a/game/client/src/main/java/net/minecraft/client/world/WorldClientMP.java b/game/client/src/main/java/net/minecraft/client/world/WorldClientMP.java
index a8ec4bc9d..7388c1042 100644
--- a/game/client/src/main/java/net/minecraft/client/world/WorldClientMP.java
+++ b/game/client/src/main/java/net/minecraft/client/world/WorldClientMP.java
@@ -10,12 +10,15 @@ import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.net.packet.PacketDisconnect;
 import net.minecraft.core.world.Dimension;
+import net.minecraft.core.world.chunk.Chunk;
 import net.minecraft.core.world.chunk.ChunkCoordinates;
 import net.minecraft.core.world.chunk.provider.IChunkProvider;
 import net.minecraft.client.world.save.SaveHandlerClientMP;
 import net.minecraft.core.world.pos.ChunkPos;
+import net.minecraft.core.world.pos.TilePos;
 import net.minecraft.core.world.pos.TilePosc;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -56,8 +59,8 @@ public class WorldClientMP extends WorldClient {
         for (int l = 0; l < this.positionTypesList.size(); l++) {
             WorldBlockPositionType worldblockpositiontype = this.positionTypesList.get(l);
             if (--worldblockpositiontype.delayTicks == 0) {
-                super.setBlockAndMetadata(worldblockpositiontype.x, worldblockpositiontype.y, worldblockpositiontype.z, worldblockpositiontype.blockId, worldblockpositiontype.metadata);
-                super.markBlockNeedsUpdate(worldblockpositiontype.x, worldblockpositiontype.y, worldblockpositiontype.z);
+                super.setBlockTypeData(worldblockpositiontype.blockPos, worldblockpositiontype.block, worldblockpositiontype.metadata);
+                super.markBlockNeedsUpdate(worldblockpositiontype.blockPos);
                 this.positionTypesList.remove(l--);
             }
         }
@@ -71,10 +74,15 @@ public class WorldClientMP extends WorldClient {
         this.sendQueue.tick();
     }
 
-    public void removePositionTypesInBounds(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
+    public void removePositionTypesInBounds(@NotNull TilePosc min, @NotNull TilePosc max) {
         for (int i = 0; i < this.positionTypesList.size(); i++) {
             WorldBlockPositionType worldblockpositiontype = this.positionTypesList.get(i);
-            if (worldblockpositiontype.x >= minX && worldblockpositiontype.y >= minY && worldblockpositiontype.z >= minZ && worldblockpositiontype.x <= maxX && worldblockpositiontype.y <= maxY && worldblockpositiontype.z <= maxZ) {
+            if (worldblockpositiontype.blockPos.x() >= min.x() &&
+                worldblockpositiontype.blockPos.y() >= min.y() &&
+                worldblockpositiontype.blockPos.z() >= min.z() &&
+                worldblockpositiontype.blockPos.x() <= max.x() &&
+                worldblockpositiontype.blockPos.y() <= max.y() &&
+                worldblockpositiontype.blockPos.z() <= max.z()) {
                 this.positionTypesList.remove(i--);
             }
         }
@@ -106,14 +114,14 @@ public class WorldClientMP extends WorldClient {
         return false;
     }
 
-    public void doPreChunk(int chunkX, int chunkZ, boolean playerAdded) {
+    public void doPreChunk(@NotNull ChunkPos chunkPos, boolean playerAdded) {
         if (playerAdded) {
-            this.chunkCache.prepareChunk(chunkX, chunkZ);
+            this.chunkCache.prepareChunk(chunkPos, true);
         } else {
-            this.chunkCache.dropChunk(new ChunkPos(chunkX, chunkZ));
+            this.chunkCache.dropChunk(chunkPos);
         }
         if (!playerAdded) {
-            markBlocksDirty(chunkX * 16, 0, chunkZ * 16, chunkX * 16 + 15, getHeightBlocks(), chunkZ * 16 + 15);
+            markBlocksDirty(new TilePos(chunkPos.x() * Chunk.CHUNK_SIZE_X, 0, chunkPos.z() * Chunk.CHUNK_SIZE_Z), new TilePos(chunkPos.x() * Chunk.CHUNK_SIZE_X + 15, getHeightBlocks(), chunkPos.z() * Chunk.CHUNK_SIZE_Z + 15));
         }
     }
 
@@ -165,7 +173,7 @@ public class WorldClientMP extends WorldClient {
         return this.entitiesById.get(i);
     }
 
-    public Entity removeEntityFromWorld(int i) {
+    public @Nullable Entity removeEntityFromWorld(int i) {
         Entity entity = this.entitiesById.remove(i);
         if (entity != null) {
             this.forced.remove(entity);
@@ -179,7 +187,7 @@ public class WorldClientMP extends WorldClient {
         final @NotNull Block<?> block = this.getBlockType(tilePos);
         final int currentData = this.getBlockData(tilePos);
         if (super.setBlockData(tilePos, data)) {
-            this.positionTypesList.add(new WorldBlockPositionType(tilePos.x(), tilePos.y(), tilePos.z(), block.id(), currentData));
+            this.positionTypesList.add(new WorldBlockPositionType(tilePos, block, currentData));
             return true;
         } else {
             return false;
@@ -191,7 +199,7 @@ public class WorldClientMP extends WorldClient {
         final @NotNull Block<?> currentBlock = this.getBlockType(tilePos);
         final int currentData = this.getBlockData(tilePos);
         if (super.setBlockTypeData(tilePos, block, data)) {
-            this.positionTypesList.add(new WorldBlockPositionType(tilePos.x(), tilePos.y(), tilePos.z(), currentBlock.id(), currentData));
+            this.positionTypesList.add(new WorldBlockPositionType(tilePos, currentBlock, currentData));
             return true;
         } else {
             return false;
@@ -203,17 +211,17 @@ public class WorldClientMP extends WorldClient {
         final @NotNull Block<?> currentBlock = this.getBlockType(tilePos);
         final int currentData = this.getBlockData(tilePos);
         if (super.setBlockType(tilePos, block)) {
-            this.positionTypesList.add(new WorldBlockPositionType(tilePos.x(), tilePos.y(), tilePos.z(), currentBlock.id(), currentData));
+            this.positionTypesList.add(new WorldBlockPositionType(tilePos, currentBlock, currentData));
             return true;
         } else {
             return false;
         }
     }
 
-    public boolean blockChange(int x, int y, int z, int id, int meta) {
-        removePositionTypesInBounds(x, y, z, x, y, z);
-        if (super.setBlockAndMetadata(x, y, z, id, meta)) {
-            notifyBlockChange(x, y, z, id);
+    public boolean blockChange(@NotNull TilePosc blockPos, @NotNull Block<?> block, int meta) {
+        removePositionTypesInBounds(blockPos, blockPos);
+        if (super.setBlockTypeData(blockPos, block, meta)) {
+            notifyBlockChange(blockPos, block);
             return true;
         } else {
             return false;
@@ -231,19 +239,15 @@ public class WorldClientMP extends WorldClient {
     }
 
     static class WorldBlockPositionType {
-        int x;
-        int y;
-        int z;
+        final @NotNull TilePosc blockPos;
         int delayTicks;
-        int blockId;
-        int metadata;
+        final @NotNull Block<?> block;
+        final int metadata;
 
-        public WorldBlockPositionType(int x, int y, int z, int blockId, int metadata) {
-            this.x = x;
-            this.y = y;
-            this.z = z;
+        public WorldBlockPositionType(@NotNull TilePosc blockPos, @NotNull Block<?> block, int metadata) {
+            this.blockPos = new TilePos(blockPos);
             this.delayTicks = 80;
-            this.blockId = blockId;
+            this.block = block;
             this.metadata = metadata;
         }
     }
diff --git a/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderClient.java b/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderClient.java
index e8671ca22..cb86c1179 100644
--- a/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderClient.java
+++ b/game/client/src/main/java/net/minecraft/client/world/chunk/provider/ChunkProviderClient.java
@@ -1,5 +1,6 @@
 package net.minecraft.client.world.chunk.provider;
 
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
 import net.minecraft.core.world.ProgressListener;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.chunk.Chunk;
@@ -11,24 +12,32 @@ import org.jetbrains.annotations.Nullable;
 
 import java.util.*;
 
-public class ChunkProviderClient
-    implements IChunkProvider {
+public class ChunkProviderClient implements IChunkProvider {
+    protected static final @NotNull ChunkPos MIN_POS = new ChunkPos(Integer.MIN_VALUE, Integer.MIN_VALUE);
+
     private final @NotNull Chunk blankChunk;
-    private final @NotNull Map<ChunkPos, Chunk> chunkMapping;
-    private final @NotNull List<Chunk> chunks;
-    private final @NotNull World worldObj;
+    private final @NotNull Map<ChunkPos, Chunk> chunkMapping = new Object2ObjectOpenHashMap<>();
+    private final @NotNull World world;
+
 
+    protected @NotNull Chunk lastQueriedChunk;
+    protected @NotNull ChunkPos lastQueriedChunkPos = MIN_POS;
 
     public ChunkProviderClient(@NotNull World world) {
-        this.chunkMapping = new HashMap<>();
-        this.chunks = new ArrayList<>();
-        this.blankChunk = new EmptyChunk(world, 0, 0);
-        this.worldObj = world;
+        this.blankChunk = new EmptyChunk(world, new ChunkPos(0, 0));
+        this.lastQueriedChunk = this.blankChunk;
+        this.world = world;
     }
 
     @Override
     public boolean isChunkLoaded(@NotNull ChunkPos chunkPos) {
-        return this.chunkMapping.containsKey(chunkPos);
+        if (chunkPos.equals(this.lastQueriedChunkPos)) return true;
+        if (this.chunkMapping.containsKey(chunkPos)) {
+            this.lastQueriedChunkPos = new ChunkPos(chunkPos);
+            this.lastQueriedChunk = this.chunkMapping.get(chunkPos);
+            return true;
+        }
+        return false;
     }
 
     @Override
@@ -41,13 +50,12 @@ public class ChunkProviderClient
             chunk.onUnload();
         }
         this.chunkMapping.remove(chunkPos);
-        this.chunks.remove(chunk);
     }
 
     @Override
     public @NotNull Chunk prepareChunk(@NotNull ChunkPos chunkPos, boolean priority) {
         if (this.chunkMapping.containsKey(chunkPos)) return this.chunkMapping.get(chunkPos);
-        Chunk chunk = new Chunk(this.worldObj, new ChunkPos(chunkPos));
+        Chunk chunk = new Chunk(this.world, new ChunkPos(chunkPos));
         this.chunkMapping.put(chunk.pos, chunk);
         chunk.isLoaded = true;
         return chunk;
@@ -55,17 +63,18 @@ public class ChunkProviderClient
 
     @Override
     public @NotNull Chunk provideChunk(@NotNull ChunkPos chunkPos, boolean priority) {
+        if (chunkPos.equals(this.lastQueriedChunkPos)) return this.lastQueriedChunk;
         Chunk chunk = this.chunkMapping.get(chunkPos);
-        if (chunk == null) {
-            return this.blankChunk;
-        } else {
+        if (chunk != null) {
+            this.lastQueriedChunkPos = chunkPos;
+            this.lastQueriedChunk = chunk;
             return chunk;
         }
+        return this.blankChunk;
     }
 
     @Override
     public boolean saveChunks(boolean saveImmediately, @Nullable ProgressListener progressListener) {
-
         return true;
     }
 
diff --git a/game/client/src/main/java/org/useless/dragonfly/DisplayPos.java b/game/client/src/main/java/org/useless/dragonfly/DisplayPos.java
index 6f4c58628..e13df5d80 100644
--- a/game/client/src/main/java/org/useless/dragonfly/DisplayPos.java
+++ b/game/client/src/main/java/org/useless/dragonfly/DisplayPos.java
@@ -7,7 +7,7 @@ import com.google.gson.JsonObject;
 import com.google.gson.JsonParseException;
 import com.google.gson.JsonSerializationContext;
 import com.google.gson.JsonSerializer;
-import net.minecraft.client.render.block.model.BlockModel;
+import org.jetbrains.annotations.NotNull;
 import org.useless.dragonfly.data.block.mojang.BlockModelMojangData;
 import org.useless.util.GsonHelper;
 
diff --git a/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/CompiledBlockModelMojangData.java b/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/CompiledBlockModelMojangData.java
index c5a46949c..abaebad9a 100644
--- a/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/CompiledBlockModelMojangData.java
+++ b/game/client/src/main/java/org/useless/dragonfly/data/block/mojang/CompiledBlockModelMojangData.java
@@ -18,7 +18,6 @@ import org.joml.Vector3f;
 import org.joml.Vector3fc;
 import org.slf4j.Logger;
 import org.useless.dragonfly.DisplayPos;
-import org.useless.dragonfly.data.block.BlockModelData;
 
 import java.util.Map;
 
@@ -69,6 +68,15 @@ public class CompiledBlockModelMojangData {
 
         this.displayPosMap = new Object2ObjectOpenHashMap<>();
         if (data.displayPositions != null) this.displayPosMap.putAll(data.displayPositions);
+        if (!this.displayPosMap.containsKey(DisplayPos.FIRST_PERSON_LEFT_HAND) && this.displayPosMap.containsKey(DisplayPos.FIRST_PERSON_RIGHT_HAND)) {
+            var right = this.displayPosMap.getOrDefault(DisplayPos.FIRST_PERSON_RIGHT_HAND, DisplayPos.DEFAULT_DISPLAY_POS);
+            var left = new DisplayPos(right.tx, right.ty, right.tz, right.rx, right.ry + 180, right.rz, right.sx, right.sy, right.sz);
+            this.displayPosMap.put(DisplayPos.FIRST_PERSON_LEFT_HAND, left);
+        }
+        if (!this.displayPosMap.containsKey(DisplayPos.THIRD_PERSON_LEFT_HAND) && this.displayPosMap.containsKey(DisplayPos.THIRD_PERSON_RIGHT_HAND)) {
+            var right = this.displayPosMap.getOrDefault(DisplayPos.THIRD_PERSON_RIGHT_HAND, DisplayPos.DEFAULT_DISPLAY_POS);
+            this.displayPosMap.put(DisplayPos.THIRD_PERSON_LEFT_HAND, right);
+        }
 
         this.particleIndices = new int[6];
         if (data.particleIndices != null) {
diff --git a/game/client/src/main/java/org/useless/dragonfly/data/entity/mojang/EntityGeometryMojangData.java b/game/client/src/main/java/org/useless/dragonfly/data/entity/mojang/EntityGeometryMojangData.java
index 1770709c5..b8b725172 100644
--- a/game/client/src/main/java/org/useless/dragonfly/data/entity/mojang/EntityGeometryMojangData.java
+++ b/game/client/src/main/java/org/useless/dragonfly/data/entity/mojang/EntityGeometryMojangData.java
@@ -33,6 +33,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -82,7 +83,7 @@ public class EntityGeometryMojangData implements EntityModelData {
         this.vBoundsOffset = vBoundsOffset;
         this.textureWidth = textureWidth;
         this.textureHeight = textureHeight;
-        this.bones = new HashMap<>();
+        this.bones = new LinkedHashMap<>();
 
         for (final Bone.Builder builder : bones) {
             @NotNull final Bone bone = builder.build();
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/birch_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/birch_fancy.json
index b24281f8f..e66ccb18a 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/birch_fancy.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/birch_fancy.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/birch_fancy"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/birch_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/birch_fast.json
index cd5b905f9..3b6d8ec25 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/birch_fast.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/birch_fast.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/birch"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/birch_smart.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/birch_smart.json
new file mode 100644
index 000000000..d550f7322
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/birch_smart.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/leaves/leaves_smart",
+  "textures": {
+    "all": "minecraft:block/leaves/birch_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_fancy.json
index fb03bbde3..a2a962303 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_fancy.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_fancy.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/cacao_fancy"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_fast.json
index e921a3911..8b289c8cc 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_fast.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_fast.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/cacao"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_smart.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_smart.json
new file mode 100644
index 000000000..759c030bc
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cacao_smart.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/leaves/leaves_smart",
+  "textures": {
+    "all": "minecraft:block/leaves/cacao_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_fancy.json
index 15705f881..2e4a70437 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_fancy.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_fancy.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/cherry_fancy"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_fast.json
index 1ac0b79bf..20a573a5d 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_fast.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_fast.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/cherry"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_smart.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_smart.json
new file mode 100644
index 000000000..d9efa030a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/cherry_smart.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/leaves/leaves_smart",
+  "textures": {
+    "all": "minecraft:block/leaves/cherry_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/eucalyptus_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/eucalyptus_fancy.json
index d4be1165a..0fc92b9f6 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/eucalyptus_fancy.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/eucalyptus_fancy.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/eucalyptus_fancy"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/eucalyptus_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/eucalyptus_fast.json
index 2d66169f1..b773bd546 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/eucalyptus_fast.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/eucalyptus_fast.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/eucalyptus"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/eucalyptus_smart.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/eucalyptus_smart.json
new file mode 100644
index 000000000..4618acd5b
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/eucalyptus_smart.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/leaves/leaves_smart",
+  "textures": {
+    "all": "minecraft:block/leaves/eucalyptus_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/template_leaves.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/leaves.json
similarity index 100%
rename from game/client/src/main/resources/assets/minecraft/models/block/template_leaves.json
rename to game/client/src/main/resources/assets/minecraft/models/block/leaves/leaves.json
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/leaves_smart.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/leaves_smart.json
new file mode 100644
index 000000000..d6a97c95a
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/leaves_smart.json
@@ -0,0 +1,41 @@
+{
+	"format_version": "1.21.6",
+	"credit": "Made with Blockbench",
+	"parent": "block/block",
+	"textures": {
+		"overlay": "#all",
+		"particle_up": "#all",
+		"particle_down": "#all",
+		"particle_north": "#all",
+		"particle_south": "#all",
+		"particle_west": "#all",
+		"particle_east": "#all"
+	},
+	"elements": [
+		{
+			"from": [0, 0, 0],
+			"to": [16, 16, 16],
+			"faces": {
+				"north": {"uv": [0, 0, 16, 16], "texture": "#all", "cullface": "north", "tintindex": 0},
+				"east": {"uv": [0, 0, 16, 16], "texture": "#all", "cullface": "east", "tintindex": 0},
+				"south": {"uv": [0, 0, 16, 16], "texture": "#all", "cullface": "south", "tintindex": 0},
+				"west": {"uv": [0, 0, 16, 16], "texture": "#all", "cullface": "west", "tintindex": 0},
+				"up": {"uv": [0, 0, 16, 16], "texture": "#all", "cullface": "up", "tintindex": 0},
+				"down": {"uv": [0, 0, 16, 16], "texture": "#all", "cullface": "down", "tintindex": 0}
+			}
+		},
+		{
+			"from": [16, 0, 0],
+			"to": [0, 16, 16],
+			"rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]},
+			"faces": {
+				"north": {"uv": [16, 0, 0, 16], "texture": "#all", "cullface": "north", "tintindex": 0},
+				"east": {"uv": [0, 0, 16, 16], "texture": "#all", "cullface": "west", "tintindex": 0},
+				"south": {"uv": [16, 0, 0, 16], "texture": "#all", "cullface": "south", "tintindex": 0},
+				"west": {"uv": [0, 0, 16, 16], "texture": "#all", "cullface": "east", "tintindex": 0},
+				"up": {"uv": [16, 0, 0, 16], "texture": "#all", "cullface": "up", "tintindex": 0},
+				"down": {"uv": [16, 0, 0, 16], "texture": "#all", "cullface": "down", "tintindex": 0}
+			}
+		}
+	]
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_fancy.json
index 4dfb1ebfe..532ae6003 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_fancy.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_fancy.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/oak_fancy"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_fast.json
index 0840288e8..c2628e6fa 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_fast.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_fast.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/oak"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_retro_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_retro_fancy.json
index 2399897f0..11cd9fce0 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_retro_fancy.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_retro_fancy.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/oak_retro_fancy"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_retro_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_retro_fast.json
index 821046f69..12958dd85 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_retro_fast.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_retro_fast.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/oak_retro"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_retro_smart.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_retro_smart.json
new file mode 100644
index 000000000..03ae8382d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_retro_smart.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/leaves/leaves_smart",
+  "textures": {
+    "all": "minecraft:block/leaves/oak_retro_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_smart.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_smart.json
new file mode 100644
index 000000000..94e58842d
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/oak_smart.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/leaves/leaves_smart",
+  "textures": {
+    "all": "minecraft:block/leaves/oak_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/palm_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/palm_fancy.json
index e7ae1fb33..a6bdce1b4 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/palm_fancy.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/palm_fancy.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/palm_fancy"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/palm_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/palm_fast.json
index 01858cd52..bdd506b48 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/palm_fast.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/palm_fast.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/palm"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/palm_smart.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/palm_smart.json
new file mode 100644
index 000000000..e60596239
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/palm_smart.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/leaves/leaves_smart",
+  "textures": {
+    "all": "minecraft:block/leaves/palm_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/pine_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/pine_fancy.json
index 55901ddae..8abd072c8 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/pine_fancy.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/pine_fancy.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/pine_fancy"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/pine_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/pine_fast.json
index aed11efb9..822be9d86 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/pine_fast.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/pine_fast.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/pine"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/pine_smart.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/pine_smart.json
new file mode 100644
index 000000000..a47b9f95f
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/pine_smart.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/leaves/leaves_smart",
+  "textures": {
+    "all": "minecraft:block/leaves/pine_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/shrub_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/shrub_fancy.json
index 7d5794ee8..d4007e5e7 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/shrub_fancy.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/shrub_fancy.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/shrub_fancy"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/shrub_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/shrub_fast.json
index 0d034e480..c700a742f 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/shrub_fast.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/shrub_fast.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/shrub"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/shrub_smart.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/shrub_smart.json
new file mode 100644
index 000000000..fde8d70d7
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/shrub_smart.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/leaves/leaves_smart",
+  "textures": {
+    "all": "minecraft:block/leaves/shrub_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/thorn_fancy.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/thorn_fancy.json
index 4a8ff6be2..155c90528 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/thorn_fancy.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/thorn_fancy.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/caatinga_fancy"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/thorn_fast.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/thorn_fast.json
index 830da6934..223f7ca84 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/leaves/thorn_fast.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/thorn_fast.json
@@ -1,5 +1,5 @@
 {
-  "parent": "minecraft:block/template_leaves",
+  "parent": "minecraft:block/leaves/leaves",
   "textures": {
     "all": "minecraft:block/leaves/caatinga"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/leaves/thorn_smart.json b/game/client/src/main/resources/assets/minecraft/models/block/leaves/thorn_smart.json
new file mode 100644
index 000000000..b7543d6b0
--- /dev/null
+++ b/game/client/src/main/resources/assets/minecraft/models/block/leaves/thorn_smart.json
@@ -0,0 +1,6 @@
+{
+  "parent": "minecraft:block/leaves/leaves_smart",
+  "textures": {
+    "all": "minecraft:block/leaves/caatinga_fancy"
+  }
+}
\ No newline at end of file
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/template_lantern_hanging.json b/game/client/src/main/resources/assets/minecraft/models/block/template_lantern_hanging.json
index 2ec7551c8..e1020271e 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/template_lantern_hanging.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/template_lantern_hanging.json
@@ -42,7 +42,7 @@
 		},
 		{
 			"from": [6, 7, 6],
-			"to": [10, 15, 10],
+			"to": [10, 13, 10],
 			"rotation": {"angle": 0, "axis": "y", "origin": [6, 1, 6]},
 			"shade": false,
 			"faces": {
diff --git a/game/client/src/main/resources/assets/minecraft/models/entity/player/player.geo.json b/game/client/src/main/resources/assets/minecraft/models/entity/player/player.geo.json
index a567e5418..295021be7 100644
--- a/game/client/src/main/resources/assets/minecraft/models/entity/player/player.geo.json
+++ b/game/client/src/main/resources/assets/minecraft/models/entity/player/player.geo.json
@@ -163,14 +163,6 @@
 						{"origin": [-4, 0, -2], "size": [4, 12, 4], "uv": [0, 16]}
 					]
 				},
-				{
-					"name": "rightPant",
-					"parent": "rightLeg",
-					"pivot": [-2, 6, 0],
-					"cubes": [
-						{"origin": [-4, 0, -2], "size": [4, 12, 4], "inflate": 0.25, "uv": [0, 32]}
-					]
-				},
 				{
 					"name": "leftLeg",
 					"parent": "body",
@@ -179,6 +171,14 @@
 						{"origin": [0, 0, -2], "size": [4, 12, 4], "uv": [16, 48]}
 					]
 				},
+				{
+					"name": "rightPant",
+					"parent": "rightLeg",
+					"pivot": [-2, 6, 0],
+					"cubes": [
+						{"origin": [-4, 0, -2], "size": [4, 12, 4], "inflate": 0.25, "uv": [0, 32]}
+					]
+				},
 				{
 					"name": "leftPant",
 					"parent": "leftLeg",
@@ -351,14 +351,6 @@
 						{"origin": [-4, 0, -2], "size": [4, 12, 4], "uv": [0, 16]}
 					]
 				},
-				{
-					"name": "rightPant",
-					"parent": "rightLeg",
-					"pivot": [-2, 6, 0],
-					"cubes": [
-						{"origin": [-4, 0, -2], "size": [4, 12, 4], "inflate": 0.25, "uv": [0, 32]}
-					]
-				},
 				{
 					"name": "leftLeg",
 					"parent": "body",
@@ -367,6 +359,14 @@
 						{"origin": [0, 0, -2], "size": [4, 12, 4], "uv": [16, 48]}
 					]
 				},
+				{
+					"name": "rightPant",
+					"parent": "rightLeg",
+					"pivot": [-2, 6, 0],
+					"cubes": [
+						{"origin": [-4, 0, -2], "size": [4, 12, 4], "inflate": 0.25, "uv": [0, 32]}
+					]
+				},
 				{
 					"name": "leftPant",
 					"parent": "leftLeg",
diff --git a/game/client/src/main/resources/shaders/photo/blur/post.fsh b/game/client/src/main/resources/shaders/photo/blur/post/post.fsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/blur/post.fsh
rename to game/client/src/main/resources/shaders/photo/blur/post/post.fsh
diff --git a/game/client/src/main/resources/shaders/photo/blur/post.vsh b/game/client/src/main/resources/shaders/photo/blur/post/post.vsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/blur/post.vsh
rename to game/client/src/main/resources/shaders/photo/blur/post/post.vsh
diff --git a/game/client/src/main/resources/shaders/photo/distantblur/post.fsh b/game/client/src/main/resources/shaders/photo/distantblur/post/post.fsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/distantblur/post.fsh
rename to game/client/src/main/resources/shaders/photo/distantblur/post/post.fsh
diff --git a/game/client/src/main/resources/shaders/photo/distantblur/post.vsh b/game/client/src/main/resources/shaders/photo/distantblur/post/post.vsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/distantblur/post.vsh
rename to game/client/src/main/resources/shaders/photo/distantblur/post/post.vsh
diff --git a/game/client/src/main/resources/shaders/photo/eerie/post.fsh b/game/client/src/main/resources/shaders/photo/eerie/post/post.fsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/eerie/post.fsh
rename to game/client/src/main/resources/shaders/photo/eerie/post/post.fsh
diff --git a/game/client/src/main/resources/shaders/photo/eerie/post.vsh b/game/client/src/main/resources/shaders/photo/eerie/post/post.vsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/eerie/post.vsh
rename to game/client/src/main/resources/shaders/photo/eerie/post/post.vsh
diff --git a/game/client/src/main/resources/shaders/photo/inverted/post.fsh b/game/client/src/main/resources/shaders/photo/inverted/post/post.fsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/inverted/post.fsh
rename to game/client/src/main/resources/shaders/photo/inverted/post/post.fsh
diff --git a/game/client/src/main/resources/shaders/photo/inverted/post.vsh b/game/client/src/main/resources/shaders/photo/inverted/post/post.vsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/inverted/post.vsh
rename to game/client/src/main/resources/shaders/photo/inverted/post/post.vsh
diff --git a/game/client/src/main/resources/shaders/photo/outline/post.fsh b/game/client/src/main/resources/shaders/photo/outline/post/post.fsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/outline/post.fsh
rename to game/client/src/main/resources/shaders/photo/outline/post/post.fsh
diff --git a/game/client/src/main/resources/shaders/photo/outline/post.vsh b/game/client/src/main/resources/shaders/photo/outline/post/post.vsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/outline/post.vsh
rename to game/client/src/main/resources/shaders/photo/outline/post/post.vsh
diff --git a/game/client/src/main/resources/shaders/photo/outline2/post.fsh b/game/client/src/main/resources/shaders/photo/outline2/post/post.fsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/outline2/post.fsh
rename to game/client/src/main/resources/shaders/photo/outline2/post/post.fsh
diff --git a/game/client/src/main/resources/shaders/photo/outline2/post.vsh b/game/client/src/main/resources/shaders/photo/outline2/post/post.vsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/outline2/post.vsh
rename to game/client/src/main/resources/shaders/photo/outline2/post/post.vsh
diff --git a/game/client/src/main/resources/shaders/photo/sepia/post.fsh b/game/client/src/main/resources/shaders/photo/sepia/post/post.fsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/sepia/post.fsh
rename to game/client/src/main/resources/shaders/photo/sepia/post/post.fsh
diff --git a/game/client/src/main/resources/shaders/photo/sepia/post.vsh b/game/client/src/main/resources/shaders/photo/sepia/post/post.vsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/sepia/post.vsh
rename to game/client/src/main/resources/shaders/photo/sepia/post/post.vsh
diff --git a/game/client/src/main/resources/shaders/photo/silhouette/post.fsh b/game/client/src/main/resources/shaders/photo/silhouette/post/post.fsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/silhouette/post.fsh
rename to game/client/src/main/resources/shaders/photo/silhouette/post/post.fsh
diff --git a/game/client/src/main/resources/shaders/photo/silhouette/post.vsh b/game/client/src/main/resources/shaders/photo/silhouette/post/post.vsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/silhouette/post.vsh
rename to game/client/src/main/resources/shaders/photo/silhouette/post/post.vsh
diff --git a/game/client/src/main/resources/shaders/photo/tiltshift/post.fsh b/game/client/src/main/resources/shaders/photo/tiltshift/post/post.fsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/tiltshift/post.fsh
rename to game/client/src/main/resources/shaders/photo/tiltshift/post/post.fsh
diff --git a/game/client/src/main/resources/shaders/photo/tiltshift/post.vsh b/game/client/src/main/resources/shaders/photo/tiltshift/post/post.vsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/tiltshift/post.vsh
rename to game/client/src/main/resources/shaders/photo/tiltshift/post/post.vsh
diff --git a/game/client/src/main/resources/shaders/photo/vignette/post.fsh b/game/client/src/main/resources/shaders/photo/vignette/post/post.fsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/vignette/post.fsh
rename to game/client/src/main/resources/shaders/photo/vignette/post/post.fsh
diff --git a/game/client/src/main/resources/shaders/photo/vignette/post.vsh b/game/client/src/main/resources/shaders/photo/vignette/post/post.vsh
similarity index 100%
rename from game/client/src/main/resources/shaders/photo/vignette/post.vsh
rename to game/client/src/main/resources/shaders/photo/vignette/post/post.vsh
diff --git a/game/core/src/main/java/net/minecraft/core/achievement/stat/StatsCounter.java b/game/core/src/main/java/net/minecraft/core/achievement/stat/StatsCounter.java
index 6fd868976..1b9a6ece7 100644
--- a/game/core/src/main/java/net/minecraft/core/achievement/stat/StatsCounter.java
+++ b/game/core/src/main/java/net/minecraft/core/achievement/stat/StatsCounter.java
@@ -1,10 +1,7 @@
 package net.minecraft.core.achievement.stat;
 
 import java.io.File;
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.Locale;
-import java.util.Map;
 import java.util.UUID;
 
 import com.b100.json.JsonParser;
@@ -23,6 +20,7 @@ import net.minecraft.core.player.Session;
 import net.minecraft.core.util.HardIllegalArgumentException;
 import net.minecraft.core.util.collection.NamespaceID;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.jetbrains.annotations.Unmodifiable;
 import org.slf4j.Logger;
 
@@ -103,7 +101,7 @@ public class StatsCounter {
 		return achievement.parent == null || isUnlocked(achievement.parent);
 	}
 
-	public int readStat(Stat stat) {
+	public int readStat(@Nullable Stat stat) {
 		return sessionStats.getOrDefault(stat, 0);
 	}
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogic.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogic.java
index 77fa14be5..c52700d53 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogic.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogic.java
@@ -383,7 +383,7 @@ public class BlockLogic implements BlockInterface, IItemConvertible {
 
     @Override
     public void onHarvest(final @NotNull World world, final @NotNull Player player, final @NotNull TilePosc tilePos, final int data, final @Nullable TileEntity tileEntity) {
-        player.addStat(Objects.requireNonNull(this.block.getStat(StatList.STAT_MINED)), 1);
+        player.addStat(this.block.getStat(StatList.STAT_MINED), 1);
 
         final @Nullable ItemStack heldItemStack = player.inventory.getCurrentItem();
         final @Nullable Item heldItem;
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluid.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluid.java
index 374ef8cd2..82fb7ea0d 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluid.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicFluid.java
@@ -144,7 +144,7 @@ public abstract class BlockLogicFluid extends BlockLogic {
         if (vec.x() == 0.0D && vec.z() == 0.0D) {
             return -1000D;
         } else {
-            return Math.atan2(vec.z(), vec.x()) - Math.PI / 2;
+            return Math.atan2(vec.z(), vec.x());
         }
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSpikes.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSpikes.java
index 88bba9d1e..b52c96889 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSpikes.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSpikes.java
@@ -10,6 +10,7 @@ import net.minecraft.core.entity.Mob;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.enums.EnumDropCause;
 import net.minecraft.core.item.ItemStack;
+import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.LevelListener;
 import net.minecraft.core.world.World;
@@ -25,6 +26,7 @@ import org.joml.primitives.AABBdc;
 public class BlockLogicSpikes extends BlockLogic
 {
     public static final int MASK_POWERED = 0b0000_0001;
+    public static final int MASK_DIRECTION = 0b0000_1110;
 
     public BlockLogicSpikes(Block<?> block, Material mat)
     {
@@ -41,8 +43,12 @@ public class BlockLogicSpikes extends BlockLogic
 
         int meta = world.getBlockData(tilePos);
         if(world.hasNeighborSignal(tilePos)) {
-            world.setBlockDataNotify(tilePos, meta | MASK_POWERED);
+            meta |= MASK_POWERED;
         }
+
+        meta |= ((side.getOpposite().getId() << 1) & MASK_DIRECTION);
+
+        world.setBlockDataNotify(tilePos, meta);
     }
 
     @Override
@@ -64,19 +70,26 @@ public class BlockLogicSpikes extends BlockLogic
 		if(isPowered != wasPowered) {
 			if(isPowered) {
 				world.playBlockEvent(null, tilePos, LevelListener.EVENT_PISTON_RETRACT, 0);
-				world.setBlockDataNotify(tilePos, MASK_POWERED);
+				world.setBlockDataNotify(tilePos, meta | MASK_POWERED);
 			}else {
 				world.playBlockEvent(null, tilePos, LevelListener.EVENT_PISTON_EXTEND, 0);
-				world.setBlockDataNotify(tilePos, 0);
+				world.setBlockDataNotify(tilePos, meta & ~MASK_POWERED);
 			}
 		}
 	}
 
-
     @Override
-    public @Nullable AABBdc getCollisionAABB(@NotNull WorldSource source, @NotNull TilePosc tilePos) {
+    public @NotNull AABBdc getBoundsFromState(@NotNull WorldSource source, @NotNull TilePosc tilePos) {
         double thickness = 3/16d;
-        return new AABBd(tilePos.x(), tilePos.y(), tilePos.z(), tilePos.x() + 1,tilePos.y() + thickness, tilePos.z() + 1);
+        Direction direction = getDirectionFromData(source.getBlockData(tilePos));
+        return switch (direction) {
+            case UP -> new AABBd(0, 1 - thickness, 0, 1, 1, 1);
+            case NORTH -> new AABBd(0, 0, 0, 1, 1, thickness);
+            case SOUTH -> new AABBd(0, 0, 1 - thickness, 1, 1, 1);
+            case WEST -> new AABBd(0, 0, 0, thickness, 1, 1);
+            case EAST -> new AABBd(1 - thickness, 0, 0, 1, 1, 1);
+            default -> new AABBd(0, 0, 0, 1,thickness, 1);
+        };
     }
 
     @Override
@@ -122,6 +135,10 @@ public class BlockLogicSpikes extends BlockLogic
         return false;
     }
 
+    public static @NotNull Direction getDirectionFromData(int data) {
+        return Direction.getDirectionById((data & MASK_DIRECTION) >> 1);
+    }
+
     @Override
     public @NotNull ISupport getSupport(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side) {
         return side == Side.BOTTOM ? FullSupport.INSTANCE : PartialSupport.INSTANCE;
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 a3b0048bf..efeb20e1a 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
@@ -1384,12 +1384,11 @@ public final class Blocks {
         }
     }
 
-    public static @Nullable Block<?> getBlock(int id)
-    {
-        if (id < 0 || id >= Blocks.blocksList.length) {
-            return null;
-        }
-        return Blocks.blocksList[id];
+    public static @NotNull Block<?> getBlock(int id) {
+        if (id < 0 || id >= Blocks.blocksList.length) return Blocks.AIR;
+        Block<?> block = Blocks.blocksList[id];
+        if (block == null) return Blocks.AIR;
+        return block;
     }
 
     public static boolean hasTag(int id, Tag<Block<?>> tag)
diff --git a/game/core/src/main/java/net/minecraft/core/data/registry/Registry.java b/game/core/src/main/java/net/minecraft/core/data/registry/Registry.java
index f4552b196..1903e6bf6 100644
--- a/game/core/src/main/java/net/minecraft/core/data/registry/Registry.java
+++ b/game/core/src/main/java/net/minecraft/core/data/registry/Registry.java
@@ -5,6 +5,7 @@ import com.mojang.nbt.tags.IntTag;
 import com.mojang.nbt.tags.Tag;
 import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
 import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.*;
@@ -153,6 +154,20 @@ public class Registry<T>
         return items.size();
     }
 
+    /**
+     * @return Collection of all registered value
+     */
+    public @NotNull Collection<T> values() {
+        return items;
+    }
+
+    /**
+     * @return Set of all registered keys
+     */
+    public @NotNull Set<String> keySet() {
+        return this.keyItemMap.keySet();
+    }
+
     @Override
     public Iterator<T> iterator() {
         return items.iterator();
diff --git a/game/core/src/main/java/net/minecraft/core/entity/Entity.java b/game/core/src/main/java/net/minecraft/core/entity/Entity.java
index 27f6908a4..0c5cb84ea 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/Entity.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/Entity.java
@@ -887,32 +887,32 @@ public abstract class Entity
         setPos(this.x, this.y, this.z);
     }
 
-    public float distanceTo(Entity entity) {
-        float f = (float) (this.x - entity.x);
-        float f1 = (float) (this.y - entity.y);
-        float f2 = (float) (this.z - entity.z);
-        return MathHelper.sqrt_float(f * f + f1 * f1 + f2 * f2);
+    public float distanceTo(@NotNull Entity entity) {
+        float dx = (float) (this.x - entity.x);
+        float dy = (float) (this.y - entity.y);
+        float dz = (float) (this.z - entity.z);
+        return MathHelper.sqrt_float(dx * dx + dy * dy + dz * dz);
     }
 
-    public double distanceToSqr(double d, double d1, double d2) {
-        double d3 = this.x - d;
-        double d4 = this.y - d1;
-        double d5 = this.z - d2;
-        return d3 * d3 + d4 * d4 + d5 * d5;
+    public double distanceToSqr(double x, double y, double z) {
+        double dx = this.x - x;
+        double dy = this.y - y;
+        double dz = this.z - z;
+        return dx * dx + dy * dy + dz * dz;
     }
 
-    public double distanceTo(double d, double d1, double d2) {
-        double d3 = this.x - d;
-        double d4 = this.y - d1;
-        double d5 = this.z - d2;
-        return MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5);
+    public double distanceTo(double x, double y, double z) {
+        double dx = this.x - x;
+        double dy = this.y - y;
+        double dz = this.z - z;
+        return MathHelper.sqrt(dx * dx + dy * dy + dz * dz);
     }
 
-    public double distanceToSqr(Entity entity) {
-        double d = this.x - entity.x;
-        double d1 = this.y - entity.y;
-        double d2 = this.z - entity.z;
-        return d * d + d1 * d1 + d2 * d2;
+    public double distanceToSqr(@NotNull Entity entity) {
+        double dx = this.x - entity.x;
+        double dy = this.y - entity.y;
+        double dz = this.z - entity.z;
+        return dx * dx + dy * dy + dz * dz;
     }
 
     public void playerTouch(Player player) {
diff --git a/game/core/src/main/java/net/minecraft/core/entity/Mob.java b/game/core/src/main/java/net/minecraft/core/entity/Mob.java
index 68e76d4b4..41e12751f 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/Mob.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/Mob.java
@@ -1134,6 +1134,13 @@ public abstract class Mob extends Entity {
         return 4;
     }
 
+    /**
+     * @return Max amount of entity within the spawn radius of the player, -1 to disable check
+     */
+    public int getMaxPerPlayer() {
+        return -1;
+    }
+
     @Override
     public void handleEntityEvent(byte byte0, float attackedAtYaw) {
         if (byte0 == 2) {
diff --git a/game/core/src/main/java/net/minecraft/core/entity/monster/MobGhast.java b/game/core/src/main/java/net/minecraft/core/entity/monster/MobGhast.java
index 47b147bf1..e58ae8690 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/monster/MobGhast.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/monster/MobGhast.java
@@ -242,6 +242,11 @@ public class MobGhast extends MobFlying
         return 1;
     }
 
+    @Override
+    public int getMaxPerPlayer() {
+        return 3;
+    }
+
     @Override
     public float calcBrightness(float partialTick) {
         return 1;
diff --git a/game/core/src/main/java/net/minecraft/core/entity/player/Player.java b/game/core/src/main/java/net/minecraft/core/entity/player/Player.java
index 3971b38eb..cc857a6c3 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/player/Player.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/player/Player.java
@@ -1317,10 +1317,10 @@ public abstract class Player
         addStat(statbase, 1);
     }
 
-    public void addStat(Stat statbase, int i) {
+    public void addStat(@Nullable Stat stat, int i) {
     }
 
-    public int getStat(Stat statbase) {
+    public int getStat(@Nullable Stat stat) {
         return 0;
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/item/ItemStatue.java b/game/core/src/main/java/net/minecraft/core/item/ItemStatue.java
index accb5a936..b60c5d684 100644
--- a/game/core/src/main/java/net/minecraft/core/item/ItemStatue.java
+++ b/game/core/src/main/java/net/minecraft/core/item/ItemStatue.java
@@ -1,6 +1,7 @@
 package net.minecraft.core.item;
 
 import net.minecraft.core.block.Block;
+import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.block.entity.TileEntityActivator;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.enums.EnumBlockSoundEffectType;
@@ -44,6 +45,14 @@ public class ItemStatue extends Item {
         world.playBlockSoundEffect(player, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.statueBlockBottom, EnumBlockSoundEffectType.PLACE);
         this.statueBlockBottom.onPlacedByMob(world, blockPos, side, player, xHit, yHit);
         this.statueBlockTop.onPlacedByMob(world, blockPos.up(new TilePos()), side, player, xHit, yHit);
+
+        if (this.statueBlockBottom.isEntityTile && selfStack.getData().containsKey("tileEntityData")) {
+            TileEntity tileEntity = world.getTileEntity(blockPos);
+            if (tileEntity != null) {
+                tileEntity.readAdditionalData(selfStack.getData().getCompound("tileEntityData"));
+            }
+        }
+
         selfStack.consumeItem(player);
         return true;
     }
@@ -66,6 +75,14 @@ public class ItemStatue extends Item {
         world.playBlockSoundEffect(null, blockPos.x() + 0.5F, blockPos.y() + 0.5F, blockPos.z() + 0.5F, this.statueBlockBottom, EnumBlockSoundEffectType.PLACE);
         this.statueBlockBottom.onPlacedOnSide(world, blockPos, direction.getSide(), 0.5, 0.5);
         this.statueBlockTop.onPlacedOnSide(world, blockPos.up(new TilePos()), direction.getSide(), 0.5, 0.5);
+
+        if (this.statueBlockBottom.isEntityTile && selfStack.getData().containsKey("tileEntityData")) {
+            TileEntity tileEntity = world.getTileEntity(blockPos);
+            if (tileEntity != null) {
+                tileEntity.readAdditionalData(selfStack.getData().getCompound("tileEntityData"));
+            }
+        }
+
         selfStack.consumeItem(null);
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/net/command/CommandManager.java b/game/core/src/main/java/net/minecraft/core/net/command/CommandManager.java
index 9b6699b7d..cd531c8bf 100644
--- a/game/core/src/main/java/net/minecraft/core/net/command/CommandManager.java
+++ b/game/core/src/main/java/net/minecraft/core/net/command/CommandManager.java
@@ -16,22 +16,27 @@ public class CommandManager {
         this.isServer = isServer;
     }
 
-    private final CommandDispatcher<CommandSource> DISPATCHER = new CommandDispatcher<>();
+    private CommandDispatcher<CommandSource> DISPATCHER = new CommandDispatcher<>();
     private static final Collection<CommandRegistry> externalCommands = new ArrayList<>();
     private static final Collection<CommandRegistry> externalServerCommands = new ArrayList<>();
 
     public void init() {
         if (this.isServer) {
             for (CommandRegistry registry : externalServerCommands) {
-                registry.register(DISPATCHER);
+                registry.register(this.DISPATCHER);
             }
         }
 
         for (CommandRegistry registry : externalCommands) {
-            registry.register(DISPATCHER);
+            registry.register(this.DISPATCHER);
         }
     }
 
+    public void reload() {
+        this.DISPATCHER = new CommandDispatcher<>();
+        init();
+    }
+
     public int execute(String s, CommandSource commandSource) throws CommandSyntaxException {
         return this.DISPATCHER.execute(s, commandSource);
     }
diff --git a/game/core/src/main/java/net/minecraft/core/net/command/arguments/ArgumentTypeGameMode.java b/game/core/src/main/java/net/minecraft/core/net/command/arguments/ArgumentTypeGameMode.java
index 431217d1d..ec768120f 100644
--- a/game/core/src/main/java/net/minecraft/core/net/command/arguments/ArgumentTypeGameMode.java
+++ b/game/core/src/main/java/net/minecraft/core/net/command/arguments/ArgumentTypeGameMode.java
@@ -26,13 +26,37 @@ public class ArgumentTypeGameMode implements ArgumentType<Gamemode> {
 
     @Override
     public Gamemode parse(StringReader reader) throws CommandSyntaxException {
-        final String string = reader.readString();
+        StringBuilder builder = new StringBuilder();
+        while (reader.canRead()) {
+            char peak = reader.peek();
+            if (peak == '[' || peak == '{' || peak == ' ') {
+                break;
+            }
+            builder.append(reader.read());
+        }
+        final String string = builder.toString();
 
+        String gamemodeString = string;
+        if (!string.contains(":")) {
+            if (!string.contains("gamemode/")) {
+                gamemodeString = "gamemode/" + string;
+            }
+        } else {
+            int colonIndex = string.indexOf(":");
+            String namespace = string.substring(0, colonIndex);
+            String value = string.substring(colonIndex + 1);
+            if (!string.contains("gamemode/")) {
+                gamemodeString = namespace + ":" + "gamemode/" + value;
+            }
+        }
         for (Gamemode gamemode : Registries.GAMEMODES) {
-            if (CommandHelper.matchesKeyString(gamemode.getId(), string)) {
+            if (CommandHelper.matchesKeyString(gamemode.getId(), gamemodeString)) {
                 return gamemode;
             }
         }
+        try {
+            return Gamemodes.getGamemodeByLegacyId(Integer.parseInt(string));
+        } catch (NumberFormatException ignored) {}
         throw new CommandSyntaxException(CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownArgument(), () -> I18n.getInstance().translateKey("command.argument_types.game_mode.invalid_game_mode"));
     }
 
@@ -40,7 +64,13 @@ public class ArgumentTypeGameMode implements ArgumentType<Gamemode> {
     public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
         String remaining = builder.getRemainingLowerCase();
         for (Gamemode gamemode : Registries.GAMEMODES) {
-            Optional<String> optional = CommandHelper.getStringToSuggest(gamemode.getId(), remaining);
+            String id = gamemode.getId();
+            Optional<String> optional;
+            if (id.startsWith("minecraft:")) {
+                optional = CommandHelper.getStringToSuggest(gamemode.getId().replace("minecraft:gamemode/", ""), remaining);
+            } else {
+                optional = CommandHelper.getStringToSuggest(gamemode.getId().replace("gamemode/", ""), remaining);
+            }
             optional.ifPresent(builder::suggest);
         }
         return builder.buildFuture();
diff --git a/game/core/src/main/java/net/minecraft/core/world/SpawnerMobs.java b/game/core/src/main/java/net/minecraft/core/world/SpawnerMobs.java
index 3b0e2289d..f6634fd5a 100644
--- a/game/core/src/main/java/net/minecraft/core/world/SpawnerMobs.java
+++ b/game/core/src/main/java/net/minecraft/core/world/SpawnerMobs.java
@@ -148,7 +148,9 @@ public final class SpawnerMobs {
                         final double dx = iPos.x + 0.5D;
                         final double dy = iPos.y;
                         final double dz = iPos.z + 0.5D;
-                        if (world.getClosestPlayer(dx, dy, dz, 24.0D) != null) continue;
+                        Player closest;
+                        if ((closest = world.getClosestPlayer(dx, dy, dz, 8 * 16)) == null) continue;
+                        if (closest.distanceToSqr(dx, dy, dz) < (24 * 24)) continue;
 
                         // Forbid mob spawning in a 24 block radius around spawn
                         if (checkSpawnDist) {
@@ -177,6 +179,12 @@ public final class SpawnerMobs {
                         if (countSpawned >= mobToSpawn.getMaxSpawnedInChunk()) {
                             continue chunkLoop;
                         }
+                        if (mobToSpawn.getMaxPerPlayer() >= 0) {
+                            var entities = world.getEntitiesWithinRadius(spawnListEntry.entityClass, closest.x, closest.y, closest.z, 8 * 16);
+                            if (entities.size() >= mobToSpawn.getMaxPerPlayer()) {
+                                continue chunkLoop;
+                            }
+                        }
                         ++countSpawned;
                         mobToSpawn.spawnInit();
                         world.entityJoinedWorld(mobToSpawn);
diff --git a/game/core/src/main/java/net/minecraft/core/world/World.java b/game/core/src/main/java/net/minecraft/core/world/World.java
index 347b75b44..2bc8f61dd 100644
--- a/game/core/src/main/java/net/minecraft/core/world/World.java
+++ b/game/core/src/main/java/net/minecraft/core/world/World.java
@@ -1,42 +1,37 @@
 package net.minecraft.core.world;
 
-import static net.minecraft.core.Global.*;
-
-import java.util.*;
-
 import com.mojang.logging.LogUtils;
-
 import it.unimi.dsi.fastutil.objects.ObjectArrayList;
 import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
-import net.minecraft.core.block.entity.TileEntity;
-import net.minecraft.core.block.material.Materials;
-import net.minecraft.core.block.support.ISupport;
-import net.minecraft.core.current.wire.WireHandler;
-import net.minecraft.core.entity.EntityItem;
-import net.minecraft.core.entity.animal.MobFireflyCluster;
-import net.minecraft.core.enums.Difficulty;
-import net.minecraft.core.util.debug.Debug;
 import net.minecraft.core.Global;
-import net.minecraft.core.block.Blocks;
-import net.minecraft.core.entity.player.Player;
-import net.minecraft.core.net.command.CommandManager;
-import net.minecraft.core.util.helper.Direction;
-import net.minecraft.core.util.phys.HitResult;
 import net.minecraft.core.NextTickListEntry;
 import net.minecraft.core.block.Block;
+import net.minecraft.core.block.Blocks;
+import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.block.material.Material;
+import net.minecraft.core.block.material.Materials;
+import net.minecraft.core.block.support.ISupport;
 import net.minecraft.core.block.tag.BlockTags;
+import net.minecraft.core.current.wire.WireHandler;
 import net.minecraft.core.data.gamerule.GameRule;
 import net.minecraft.core.data.gamerule.GameRules;
 import net.minecraft.core.entity.Entity;
+import net.minecraft.core.entity.EntityItem;
 import net.minecraft.core.entity.Mob;
+import net.minecraft.core.entity.animal.MobFireflyCluster;
+import net.minecraft.core.entity.player.Player;
+import net.minecraft.core.enums.Difficulty;
 import net.minecraft.core.enums.EnumBlockSoundEffectType;
 import net.minecraft.core.enums.LightLayer;
 import net.minecraft.core.item.ItemStack;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.sound.BlockSound;
 import net.minecraft.core.sound.SoundCategory;
+import net.minecraft.core.util.debug.Debug;
+import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.util.helper.Side;
+import net.minecraft.core.util.phys.HitResult;
 import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.biome.Biomes;
 import net.minecraft.core.world.biome.provider.BiomeProvider;
@@ -76,6 +71,20 @@ import org.joml.primitives.AABBd;
 import org.joml.primitives.AABBdc;
 import org.slf4j.Logger;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Random;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.UUID;
+
+import static net.minecraft.core.Global.DAY_LENGTH_TICKS;
+import static net.minecraft.core.Global.accessor;
+import static net.minecraft.core.Global.isServer;
+
 public class World implements MutableWorldSource {
     private static final Logger LOGGER = LogUtils.getLogger();
     public static boolean AUTOSAVE = true;
@@ -142,7 +151,7 @@ public class World implements MutableWorldSource {
     private final @NotNull WireHandler wireHandler;
 
     //Usually called when a world is loaded or generated (Singleplayer & Server)
-    public World(LevelStorage saveHandler, String name, long seed, Dimension dimension, WorldType worldType) {
+    public World(@NotNull LevelStorage saveHandler, @NotNull String name, long seed, @Nullable Dimension dimension, @Nullable WorldType worldType, @Nullable Biome startingBiome) {
         this.saveHandler = saveHandler;
         this.savedDataStorage = new SavedDataStorage(saveHandler);
         this.levelData = saveHandler.getLevelData();
@@ -203,7 +212,7 @@ public class World implements MutableWorldSource {
 
         if (isNewWorld) {
             this.worldType.onWorldCreation(this);
-            getInitialSpawnLocation();
+            getInitialSpawnLocation(startingBiome);
         }
         updateSkyBrightness();
 
@@ -311,9 +320,9 @@ public class World implements MutableWorldSource {
         return accessor.createChunkProvider(this, chunkLoader);
     }
 
-    protected void getInitialSpawnLocation() {
+    protected void getInitialSpawnLocation(@Nullable Biome startingBiome) {
         this.findingSpawnPoint = true;
-        getWorldType().getInitialSpawnLocation(this);
+        getWorldType().getInitialSpawnLocation(this, startingBiome);
         this.findingSpawnPoint = false;
     }
 
@@ -1251,7 +1260,6 @@ public class World implements MutableWorldSource {
     public @NotNull List<@NotNull AABBdc> getCubes(@NotNull Entity entity, @NotNull AABBdc aabb) {
         TilePos d = new TilePos(entity);
         this.collidingBoundingBoxes.clear();
-        if (!d.inBounds(this)) return this.collidingBoundingBoxes;
 
         int minX = MathHelper.floor(aabb.minX());
         int maxX = MathHelper.floor(aabb.maxX() + 1.0D);
@@ -1277,11 +1285,9 @@ public class World implements MutableWorldSource {
             for (d.z = minZ - 1; d.z <= maxZ; d.z++) {
                 for (d.y = minY - 1; d.y <= maxY; d.y++) {
                     Block<?> block = getBlockType(d);
-                    if (block != null) {
-                        int metadata = getBlockData(d);
-                        if (block.collidesWithEntity(entity, this, d) && entity.collidesWithBlock(block, metadata)) {
-                            block.getCollisionAABBs(this, d, aabb, this.collidingBoundingBoxes);
-                        }
+                    int metadata = getBlockData(d);
+                    if (block.collidesWithEntity(entity, this, d) && entity.collidesWithBlock(block, metadata)) {
+                        block.getCollisionAABBs(this, d, aabb, this.collidingBoundingBoxes);
                     }
                 }
             }
@@ -2229,6 +2235,23 @@ public class World implements MutableWorldSource {
         return entities;
     }
 
+    public <T extends Entity> @NotNull List<@NotNull T> getEntitiesWithinRadius(@NotNull Class<T> ofClass, double x, double y, double z, double radius) {
+        int minX = MathHelper.floor(x - radius);
+        int minZ = MathHelper.floor(z - radius);
+        int maxX = MathHelper.ceil(x + radius);
+        int maxZ = MathHelper.ceil(z + radius);
+        List<@NotNull T> entities = new ArrayList<>();
+        for (int bx = minX; bx <= maxX; bx++) {
+            for (int bz = minZ; bz <= maxZ; bz++) {
+                if (isChunkLoaded(bx, bz)) {
+                    getChunkFromChunkCoords(bx, bz).getEntitiesWithinRadius(ofClass, x, y, z, radius, entities);
+                }
+            }
+        }
+
+        return entities;
+    }
+
     public @NotNull List<@NotNull Entity> getLoadedEntityList() {
         return this.entities;
     }
diff --git a/game/core/src/main/java/net/minecraft/core/world/biome/Biome.java b/game/core/src/main/java/net/minecraft/core/world/biome/Biome.java
index 572aa93be..a8455e7a2 100644
--- a/game/core/src/main/java/net/minecraft/core/world/biome/Biome.java
+++ b/game/core/src/main/java/net/minecraft/core/world/biome/Biome.java
@@ -1,6 +1,15 @@
 package net.minecraft.core.world.biome;
 
-import net.minecraft.core.entity.animal.*;
+import net.minecraft.core.block.Blocks;
+import net.minecraft.core.entity.SpawnListEntry;
+import net.minecraft.core.entity.animal.MobButterfly;
+import net.minecraft.core.entity.animal.MobChicken;
+import net.minecraft.core.entity.animal.MobCow;
+import net.minecraft.core.entity.animal.MobDeer;
+import net.minecraft.core.entity.animal.MobFireflyCluster;
+import net.minecraft.core.entity.animal.MobPig;
+import net.minecraft.core.entity.animal.MobSheep;
+import net.minecraft.core.entity.animal.MobSquid;
 import net.minecraft.core.entity.monster.MobCreeper;
 import net.minecraft.core.entity.monster.MobSkeleton;
 import net.minecraft.core.entity.monster.MobSlime;
@@ -9,13 +18,15 @@ import net.minecraft.core.entity.monster.MobSpider;
 import net.minecraft.core.entity.monster.MobZombie;
 import net.minecraft.core.entity.monster.MobZombieArmored;
 import net.minecraft.core.enums.MobCategory;
-import net.minecraft.core.block.Blocks;
-import net.minecraft.core.entity.SpawnListEntry;
+import net.minecraft.core.world.World;
 import net.minecraft.core.world.generate.feature.WorldFeature;
 import net.minecraft.core.world.generate.feature.tree.WorldFeatureTree;
 import net.minecraft.core.world.generate.feature.tree.WorldFeatureTreeFancy;
+import net.minecraft.core.world.pos.TilePos;
+import net.minecraft.core.world.pos.TilePosc;
 import net.minecraft.core.world.weather.Weather;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -37,24 +48,24 @@ public class Biome
     
     public Biome(String key)
     {
-    	this.translationKey = "biome." + key; 
-        topBlock = (short) Blocks.GRASS.id();
-        fillerBlock = (short)Blocks.DIRT.id();
-        spawnableMonsterList.add(new SpawnListEntry(MobSpider.class, 10));
-        spawnableMonsterList.add(new SpawnListEntry(MobZombie.class, 10));
-        spawnableMonsterList.add(new SpawnListEntry(MobZombieArmored.class, 2));
-        spawnableMonsterList.add(new SpawnListEntry(MobSkeleton.class, 10));
-        spawnableMonsterList.add(new SpawnListEntry(MobCreeper.class, 10));
-        spawnableMonsterList.add(new SpawnListEntry(MobSlime.class, 10));
-        spawnableMonsterList.add(new SpawnListEntry(MobSnowman.class, 2));
-        spawnableCreatureList.add(new SpawnListEntry(MobSheep.class, 102));
-        spawnableCreatureList.add(new SpawnListEntry(MobPig.class, 102));
-        spawnableCreatureList.add(new SpawnListEntry(MobChicken.class, 102));
-        spawnableCreatureList.add(new SpawnListEntry(MobCow.class, 102));
-        spawnableCreatureList.add(new SpawnListEntry(MobDeer.class, 10));
-        spawnableWaterCreatureList.add(new SpawnListEntry(MobSquid.class, 10));
-        spawnableAmbientCreatureList.add(new SpawnListEntry(MobFireflyCluster.class, 10));
-        spawnableAmbientCreatureList.add(new SpawnListEntry(MobButterfly.class, 65));
+    	this.translationKey = "biome." + key;
+        this.topBlock = (short) Blocks.GRASS.id();
+        this.fillerBlock = (short)Blocks.DIRT.id();
+        this.spawnableMonsterList.add(new SpawnListEntry(MobSpider.class, 10));
+        this.spawnableMonsterList.add(new SpawnListEntry(MobZombie.class, 10));
+        this.spawnableMonsterList.add(new SpawnListEntry(MobZombieArmored.class, 2));
+        this.spawnableMonsterList.add(new SpawnListEntry(MobSkeleton.class, 10));
+        this.spawnableMonsterList.add(new SpawnListEntry(MobCreeper.class, 10));
+        this.spawnableMonsterList.add(new SpawnListEntry(MobSlime.class, 10));
+        this.spawnableMonsterList.add(new SpawnListEntry(MobSnowman.class, 2));
+        this.spawnableCreatureList.add(new SpawnListEntry(MobSheep.class, 102));
+        this.spawnableCreatureList.add(new SpawnListEntry(MobPig.class, 102));
+        this.spawnableCreatureList.add(new SpawnListEntry(MobChicken.class, 102));
+        this.spawnableCreatureList.add(new SpawnListEntry(MobCow.class, 102));
+        this.spawnableCreatureList.add(new SpawnListEntry(MobDeer.class, 10));
+        this.spawnableWaterCreatureList.add(new SpawnListEntry(MobSquid.class, 10));
+        this.spawnableAmbientCreatureList.add(new SpawnListEntry(MobFireflyCluster.class, 10));
+        this.spawnableAmbientCreatureList.add(new SpawnListEntry(MobButterfly.class, 65));
     }
 
     public WorldFeature getRandomWorldGenForTrees(Random random)
@@ -91,16 +102,16 @@ public class Biome
     public @NotNull List<@NotNull SpawnListEntry> getSpawnableList(final @NotNull MobCategory creatureType)
     {
         return switch (creatureType) {
-            case MONSTER -> spawnableMonsterList;
-            case CREATURE -> spawnableCreatureList;
-            case WATER_CREATURE -> spawnableWaterCreatureList;
-            case AMBIENT -> spawnableAmbientCreatureList;
+            case MONSTER -> this.spawnableMonsterList;
+            case CREATURE -> this.spawnableCreatureList;
+            case WATER_CREATURE -> this.spawnableWaterCreatureList;
+            case AMBIENT -> this.spawnableAmbientCreatureList;
         };
     }
     
     public boolean hasSurfaceSnow()
     {
-    	return hasSurfaceSnow;
+    	return this.hasSurfaceSnow;
     }
 
     public boolean hasSurfaceIce() {
@@ -109,7 +120,7 @@ public class Biome
 
     public Biome setSurfaceSnow()
     {
-    	hasSurfaceSnow = true;
+        this.hasSurfaceSnow = true;
     	return this;
     }
 
@@ -135,4 +146,35 @@ public class Biome
         this.fillerBlock = (short)id;
         return this;
     }
+
+    public static @Nullable TilePosc getBiomeCoords(@NotNull Biome biome, @NotNull World world) {
+        int[] xPattern = new int[]{0, 1, 0, -1};
+        int[] zPattern = new int[]{1, 0, -1, 0};
+        TilePosc sourcePos = new TilePos();
+        int runLength = 2;
+        int chunkX = (int) (sourcePos.x() / 16.0);
+        int chunkZ = (int) (sourcePos.z() / 16.0);
+        int passes = 1024;
+        if (world.getBiomeProvider().getBiome(sourcePos.x(), sourcePos.y(), sourcePos.z()) == biome) {
+            return sourcePos;
+        } else {
+            --chunkX;
+            --chunkZ;
+            for (int pass = 0; pass < passes; ++pass) {
+                for (int i = 0; i < 4; ++i) {
+                    for (int j = runLength - 1; j >= 0; --j) {
+                        chunkX += xPattern[i];
+                        chunkZ += zPattern[i];
+                        if (world.getBiomeProvider().getBiome(chunkX * 16, sourcePos.y(), chunkZ * 16) == biome) {
+                            return new TilePos(chunkX * 16, sourcePos.y(), chunkZ * 16);
+                        }
+                    }
+                }
+
+                ++runLength;
+            }
+
+            return null;
+        }
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/world/biome/data/BiomeRangeMap.java b/game/core/src/main/java/net/minecraft/core/world/biome/data/BiomeRangeMap.java
index 0ccdd749e..df60a6eac 100644
--- a/game/core/src/main/java/net/minecraft/core/world/biome/data/BiomeRangeMap.java
+++ b/game/core/src/main/java/net/minecraft/core/world/biome/data/BiomeRangeMap.java
@@ -19,7 +19,7 @@ public final class BiomeRangeMap
 
     public void addRange(Biome biome, BiomeRange... ranges)
     {
-        if (ranges == null || ranges.length == 0 || lookup != null) return;
+        if (ranges == null || ranges.length == 0 || this.lookup != null) return;
         Set<BiomeRange> set = this.ranges.getOrDefault(biome, new HashSet<>());
         set.addAll(Arrays.asList(ranges));
         this.ranges.put(biome, set);
@@ -27,7 +27,7 @@ public final class BiomeRangeMap
 
     public void lock()
     {
-        lookup = new BiomeRangeLookup(this, 50);
+        this.lookup = new BiomeRangeLookup(this, 50);
     }
 
     public Set<BiomeRange> getRanges(Biome biome)
@@ -38,9 +38,13 @@ public final class BiomeRangeMap
         return Collections.unmodifiableSet(ranges);
     }
 
+    public Set<Biome> allBiomes() {
+        return this.ranges.keySet();
+    }
+
     public void clear() {
-        lookup = null;
-        ranges.clear();
+        this.lookup = null;
+        this.ranges.clear();
     }
 
     public boolean hasGaps()
@@ -73,7 +77,7 @@ public final class BiomeRangeMap
         altitude = MathHelper.clamp(altitude, 0.0, 1.0);
         variety = MathHelper.clamp(variety, 0.0, 1.0);
 
-        return lookup.getBiome(temperature, humidity, altitude, variety);
+        return this.lookup.getBiome(temperature, humidity, altitude, variety);
     }
 
     Biome findBiome(double temperature, double humidity, double altitude, double variety)
@@ -84,7 +88,7 @@ public final class BiomeRangeMap
         variety = MathHelper.clamp(variety, 0.0, 1.0);
         Biome last = null;
 
-        for (Map.Entry<Biome, Set<BiomeRange>> entry : ranges.entrySet())
+        for (Map.Entry<Biome, Set<BiomeRange>> entry : this.ranges.entrySet())
         {
             for (BiomeRange range : entry.getValue())
             {
diff --git a/game/core/src/main/java/net/minecraft/core/world/biome/provider/BiomeProviderB173.java b/game/core/src/main/java/net/minecraft/core/world/biome/provider/BiomeProviderB173.java
index 65960f0a0..6d95fd3a7 100644
--- a/game/core/src/main/java/net/minecraft/core/world/biome/provider/BiomeProviderB173.java
+++ b/game/core/src/main/java/net/minecraft/core/world/biome/provider/BiomeProviderB173.java
@@ -3,8 +3,6 @@ package net.minecraft.core.world.biome.provider;
 import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.biome.Biomes;
 import net.minecraft.core.world.noise.FractalNoise2D;
-import net.minecraft.core.world.noise.FractalNoise3D;
-import net.minecraft.core.world.noise.Noise2D;
 import net.minecraft.core.world.noise.SimplexNoise;
 import org.jetbrains.annotations.NotNull;
 
@@ -174,4 +172,12 @@ public class BiomeProviderB173
             return humidity < 0.9 ? Biomes.OVERWORLD_LEGACY_SEASONAL_FOREST : Biomes.OVERWORLD_LEGACY_RAINFOREST;
         }
     }
+
+    public static Biome[] allBiomes() {
+        return new Biome[] {
+            Biomes.OVERWORLD_LEGACY_TUNDRA, Biomes.OVERWORLD_LEGACY_SAVANNA, Biomes.OVERWORLD_LEGACY_DESERT, Biomes.OVERWORLD_LEGACY_SWAMPLAND,
+            Biomes.OVERWORLD_LEGACY_TAIGA, Biomes.OVERWORLD_LEGACY_SHRUBLAND, Biomes.OVERWORLD_LEGACY_FOREST, Biomes.OVERWORLD_LEGACY_SEASONAL_FOREST,
+            Biomes.OVERWORLD_LEGACY_RAINFOREST
+        };
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/world/biome/provider/BiomeProviderNether.java b/game/core/src/main/java/net/minecraft/core/world/biome/provider/BiomeProviderNether.java
index 9491a3120..0d03b4adb 100644
--- a/game/core/src/main/java/net/minecraft/core/world/biome/provider/BiomeProviderNether.java
+++ b/game/core/src/main/java/net/minecraft/core/world/biome/provider/BiomeProviderNether.java
@@ -277,4 +277,8 @@ public final class BiomeProviderNether
         toUpdate.biomeAPercentage = 1.0f;
         return;
     }
+
+    public static Biome[] allBiomes() {
+        return biomesOrder;
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/world/biome/provider/BiomeProviderOverworld.java b/game/core/src/main/java/net/minecraft/core/world/biome/provider/BiomeProviderOverworld.java
index fafc504cd..b71fd7301 100644
--- a/game/core/src/main/java/net/minecraft/core/world/biome/provider/BiomeProviderOverworld.java
+++ b/game/core/src/main/java/net/minecraft/core/world/biome/provider/BiomeProviderOverworld.java
@@ -6,9 +6,7 @@ import net.minecraft.core.world.biome.Biomes;
 import net.minecraft.core.world.biome.data.BiomeRange;
 import net.minecraft.core.world.biome.data.BiomeRangeMap;
 import net.minecraft.core.world.noise.FractalNoise2D;
-import net.minecraft.core.world.noise.FractalNoise3D;
 import net.minecraft.core.world.noise.SimplexNoise;
-import net.minecraft.core.world.noise.WorleyNoise;
 import net.minecraft.core.world.type.WorldType;
 
 import java.util.Set;
@@ -17,6 +15,7 @@ public final class BiomeProviderOverworld
     extends BiomeProvider
 {
     private static final BiomeRangeMap brm = new BiomeRangeMap();
+    private static Biome[] biomes;
 
     private final FractalNoise2D<?> temperatureMap;
     private final FractalNoise2D<?> humidityMap;
@@ -398,10 +397,21 @@ public final class BiomeProviderOverworld
                 new BiomeRange(0.95, 1.0, 0.85, 1.0, 0.0, 1.0, 0.0, 1.0)
         );
         brm.lock();
+
+        var allBiomes = brm.allBiomes();
+        biomes = new Biome[allBiomes.size()];
+        int i = 0;
+        for (var biome : allBiomes) {
+            biomes[i++] = biome;
+        }
         
 //		Stop turning this on it crashes servers
 //        if (!Global.isServer){
 //            brm.generateDebugImage(true);
 //        }
     }
+
+    public static Biome[] allBiomes() {
+        return biomes;
+    }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/Chunk.java b/game/core/src/main/java/net/minecraft/core/world/chunk/Chunk.java
index ac9ff06ab..6b2860e00 100644
--- a/game/core/src/main/java/net/minecraft/core/world/chunk/Chunk.java
+++ b/game/core/src/main/java/net/minecraft/core/world/chunk/Chunk.java
@@ -703,6 +703,14 @@ public class Chunk {
         }
     }
 
+    public <T extends Entity> void getEntitiesWithinRadius(@NotNull Class<T> ofClass, double x, double y, double z, double radius, @NotNull List<@NotNull T> entities) {
+        int minSection = Math.max(0, MathHelper.floor((y - radius - 2D) / 16D));
+        int maxSection = Math.min(MathHelper.floor((y + radius + 2D) / 16D), CHUNK_SECTIONS - 1);
+        for (int section = minSection; section <= maxSection; section++) {
+            getSection(section).getEntitiesWithinRadius(ofClass, x, y, z, radius, entities);
+        }
+    }
+
     public boolean needsSaving(boolean saveImmediately) {
         if (this.neverSave) {
             return false;
diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkSection.java b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkSection.java
index 4fe64ebe8..037998bc3 100644
--- a/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkSection.java
+++ b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkSection.java
@@ -255,6 +255,15 @@ public class ChunkSection {
         }
     }
 
+    public <T extends Entity> void getEntitiesWithinRadius(@NotNull Class<T> ofClass, double x, double y, double z, double radius, @NotNull List<@NotNull T> entities) {
+        for (Entity e : this.entities) {
+            if (ofClass.isAssignableFrom(e.getClass()) && e.bb.intersectsSphere(x, y, z, radius)) {
+                //noinspection unchecked
+                entities.add((T) e);
+            }
+        }
+    }
+
     public void onLoad(World world) {
         world.addLoadedEntities(this.entities);
     }
diff --git a/game/core/src/main/java/net/minecraft/core/world/config/spawning/SpawnerConfig.java b/game/core/src/main/java/net/minecraft/core/world/config/spawning/SpawnerConfig.java
index ca50a4c41..15b9f388b 100644
--- a/game/core/src/main/java/net/minecraft/core/world/config/spawning/SpawnerConfig.java
+++ b/game/core/src/main/java/net/minecraft/core/world/config/spawning/SpawnerConfig.java
@@ -7,6 +7,7 @@ import com.mojang.nbt.tags.Tag;
 import net.minecraft.core.util.HardIllegalArgumentException;
 import net.minecraft.core.util.collection.NamespaceID;
 import net.minecraft.core.world.World;
+import org.jetbrains.annotations.NotNull;
 import org.slf4j.Logger;
 
 import java.util.Collection;
@@ -15,55 +16,63 @@ import java.util.Map;
 
 public class SpawnerConfig {
     private static final Logger LOGGER = LogUtils.getLogger();
-    private boolean allowPassive = true;
-    private boolean allowHostile = true;
+    public boolean allowPassive = true;
+    public boolean allowHostile = true;
     private final Map<NamespaceID, Boolean> mobSpawnOverrides = new HashMap<>();
 
-    public boolean canPassiveSpawn(World world) {
-        return allowPassive;
+    public boolean canPassiveSpawn(@NotNull World world) {
+        return this.allowPassive;
     }
 
     public void setPassiveSpawning(boolean flag) {
-        allowPassive = flag;
+        this.allowPassive = flag;
     }
 
-    public boolean canHostileSpawn(World world) {
-        return allowHostile && world.getDifficulty().canHostileMobsSpawn();
+    public boolean canHostileSpawn(@NotNull World world) {
+        return this.allowHostile && world.getDifficulty().canHostileMobsSpawn();
     }
 
     public void setHostileSpawning(boolean flag) {
-        allowHostile = flag;
+        this.allowHostile = flag;
     }
 
-    public boolean canMobSpawn(NamespaceID mobID) {
-        return mobSpawnOverrides.getOrDefault(mobID, true);
+    public boolean canMobSpawn(@NotNull NamespaceID mobID) {
+        return this.mobSpawnOverrides.getOrDefault(mobID, true);
     }
 
-    public void setMobSpawn(NamespaceID mobID, boolean flag) {
-        mobSpawnOverrides.put(mobID, flag);
+    public void setMobSpawn(@NotNull NamespaceID mobID, boolean flag) {
+        this.mobSpawnOverrides.put(mobID, flag);
+    }
+
+    public void set(@NotNull SpawnerConfig config) {
+        this.mobSpawnOverrides.clear();
+        this.mobSpawnOverrides.putAll(config.mobSpawnOverrides);
+
+        this.allowHostile = config.allowHostile;
+        this.allowPassive = config.allowPassive;
     }
 
     public Collection<Map.Entry<NamespaceID, Boolean>> getSpawnEntries() {
-        return mobSpawnOverrides.entrySet();
+        return this.mobSpawnOverrides.entrySet();
     }
 
     public void writeToTag(CompoundTag tag) {
-        tag.putBoolean("passive", allowPassive);
-        tag.putBoolean("hostile", allowHostile);
+        tag.putBoolean("passive", this.allowPassive);
+        tag.putBoolean("hostile", this.allowHostile);
         CompoundTag overridesTag = new CompoundTag();
-        for (Map.Entry<NamespaceID, Boolean> e : mobSpawnOverrides.entrySet()) {
+        for (Map.Entry<NamespaceID, Boolean> e : this.mobSpawnOverrides.entrySet()) {
             overridesTag.putBoolean(e.getKey().toString(), e.getValue());
         }
         tag.putCompound("overrides", overridesTag);
     }
 
     public void readFromTag(CompoundTag tag) {
-        allowPassive = tag.getBoolean("passive");
-        allowHostile = tag.getBoolean("hostile");
+        this.allowPassive = tag.getBoolean("passive");
+        this.allowHostile = tag.getBoolean("hostile");
         CompoundTag overrides = tag.getCompound("overrides");
         for (Map.Entry<String, Tag<?>> tagEntry : overrides.getValue().entrySet()) {
             try {
-                mobSpawnOverrides.put(NamespaceID.fromPool(tagEntry.getKey()).copyUnpooled(), ((ByteTag)tagEntry.getValue()).getValue() != 0);
+                this.mobSpawnOverrides.put(NamespaceID.fromPool(tagEntry.getKey()).copyUnpooled(), ((ByteTag)tagEntry.getValue()).getValue() != 0);
             } catch (HardIllegalArgumentException e) {
                 LOGGER.error("Failed to convert string '{}' to namespace id!", tagEntry.getKey(), e);
             }
diff --git a/game/core/src/main/java/net/minecraft/core/world/pos/TilePos.java b/game/core/src/main/java/net/minecraft/core/world/pos/TilePos.java
index 9822b05e3..b6b2f5a2e 100644
--- a/game/core/src/main/java/net/minecraft/core/world/pos/TilePos.java
+++ b/game/core/src/main/java/net/minecraft/core/world/pos/TilePos.java
@@ -249,7 +249,7 @@ public final class TilePos implements Externalizable, Cloneable, TilePosc {
                 this.y >= 0 &&
                 this.z >= World.MIN_BLOCK_Z &&
                 this.x <= World.MAX_BLOCK_X &&
-                this.y <= source.getHeightBlocks() &&
+                this.y < source.getHeightBlocks() &&
                 this.z <= World.MAX_BLOCK_Z;
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/world/settings/WorldConfiguration.java b/game/core/src/main/java/net/minecraft/core/world/settings/WorldConfiguration.java
index a6c0f008d..c3f680d41 100644
--- a/game/core/src/main/java/net/minecraft/core/world/settings/WorldConfiguration.java
+++ b/game/core/src/main/java/net/minecraft/core/world/settings/WorldConfiguration.java
@@ -6,9 +6,12 @@ import net.minecraft.core.player.gamemode.Gamemode;
 import net.minecraft.core.player.gamemode.Gamemodes;
 import net.minecraft.core.util.helper.ChatAllowedCharacters;
 import net.minecraft.core.util.helper.MathHelper;
+import net.minecraft.core.world.biome.Biome;
+import net.minecraft.core.world.config.spawning.SpawnerConfig;
 import net.minecraft.core.world.save.ISaveFormat;
 import net.minecraft.core.world.type.WorldTypeGroups;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.Random;
 
@@ -19,7 +22,9 @@ public class WorldConfiguration {
     private boolean cheatsEnabled = false;
     private @NotNull Gamemode gamemode = Gamemodes.SURVIVAL;
     private @NotNull WorldTypeGroups.Group worldTypeGroup = WorldTypeGroups.DEFAULT;
+    private @Nullable Biome startingBiome = null;
     private final @NotNull GameRuleCollection gameRuleCollection = new GameRuleCollection();
+    private final SpawnerConfig spawnerConfig = new SpawnerConfig();
 
     public WorldConfiguration() {
     }
@@ -101,6 +106,18 @@ public class WorldConfiguration {
         return this.gameRuleCollection;
     }
 
+    public @NotNull SpawnerConfig getSpawnerConfig() {
+        return this.spawnerConfig;
+    }
+
+    public void setStartingBiome(@Nullable Biome biome) {
+        this.startingBiome = biome;
+    }
+
+    public @Nullable Biome getStartingBiome() {
+        return this.startingBiome;
+    }
+
     public @NotNull String getFolderName(final @NotNull ISaveFormat saveFormat) {
         final char @NotNull [] ac = ChatAllowedCharacters.ALLOWED_CHARACTERS_ARRAY;
         @NotNull String folderName = this.worldName.trim();
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/WorldType.java b/game/core/src/main/java/net/minecraft/core/world/type/WorldType.java
index 0b8a7f2f2..5dba29a81 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/WorldType.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/WorldType.java
@@ -3,9 +3,12 @@ package net.minecraft.core.world.type;
 import net.minecraft.core.Global;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.world.World;
+import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.biome.provider.BiomeProvider;
 import net.minecraft.core.world.config.season.SeasonConfig;
 import net.minecraft.core.world.generate.chunk.ChunkGenerator;
+import net.minecraft.core.world.pos.TilePos;
+import net.minecraft.core.world.pos.TilePosc;
 import net.minecraft.core.world.save.LevelData;
 import net.minecraft.core.world.season.Seasons;
 import net.minecraft.core.world.weather.Weather;
@@ -140,33 +143,67 @@ public abstract class WorldType {
 
     public abstract BiomeProvider createBiomeProvider(World world);
 
+    public abstract @NotNull Biome @NotNull [] allBiomes();
+
     public abstract ChunkGenerator createChunkGenerator(World world);
 
     public abstract boolean isValidSpawn(World world, int x, int y, int z);
 
-    public void getInitialSpawnLocation(World world) {
-        int x = 0;
-        int y = 0;
-        int z = 0;
+    public void getInitialSpawnLocation(World world, @Nullable Biome startingBiome) {
+        TilePos queryPos = new TilePos();
+        TilePos spawnPos = new TilePos();
+        if (startingBiome != null) {
+            TilePosc biomePos = Biome.getBiomeCoords(startingBiome, world);
+            if (biomePos != null) {
+                spawnPos.x = biomePos.x();
+                spawnPos.z = biomePos.z();
+            }
+            Random random = new Random(world.getRandomSeed());
+            int attemptsRemaining = 10000;
+            boolean found = false;
+            while (true) {
+                if (attemptsRemaining <= 0) {
+                    spawnPos.x = 0;
+                    spawnPos.z = 0;
+                    spawnPos.y = world.getHeightValue(spawnPos.x, spawnPos.z) - 1;
+                    break;
+                }
+                spawnPos.x += random.nextInt(64) - random.nextInt(64);
+                spawnPos.z += random.nextInt(64) - random.nextInt(64);
+                spawnPos.y = world.getHeightValue(spawnPos.x, spawnPos.z) - 1;
+                if (world.getBiomeProvider().getBiome(spawnPos.x, spawnPos.y, spawnPos.z) != startingBiome) continue;
+                Block<?> b = world.getBlockType(spawnPos.up(queryPos));
+                if (b.getCollisionAABB(world, queryPos) == null && !b.getMaterial().isLiquid() && world.isBlockOpaqueCube(spawnPos)) {
+                    found = true;
+                    break;
+                }
+                attemptsRemaining--;
+            }
+            if (found) {
+                world.getLevelData().setSpawn(spawnPos.x, spawnPos.y, spawnPos.z);
+                return;
+            }
+        }
         Random random = new Random(world.getRandomSeed());
         int attemptsRemaining = 10000;
         spawnLoop:  while (true) {
             if (attemptsRemaining <= 0) {
-                x = 0;
-                z = 0;
-                y = world.getHeightValue(x, z);
+                spawnPos.x = 0;
+                spawnPos.z = 0;
+                spawnPos.y = world.getHeightValue(spawnPos.x, spawnPos.z) - 1;
                 break spawnLoop;
             }
-            x += random.nextInt(64) - random.nextInt(64);
-            z += random.nextInt(64) - random.nextInt(64);
-            for (y = getMaxY(); y >= getMinY(); y--) {
-                if (world.getBlockId(x, y + 1, z) == 0 && isValidSpawn(world, x, y, z)) {
+            spawnPos.x += random.nextInt(64) - random.nextInt(64);
+            spawnPos.z += random.nextInt(64) - random.nextInt(64);
+            for (spawnPos.y = getMaxY(); spawnPos.y >= getMinY(); spawnPos.y--) {
+                Block<?> b = world.getBlockType(spawnPos.up(queryPos));
+                if (b.getCollisionAABB(world, queryPos) == null && !b.getMaterial().isLiquid() && isValidSpawn(world, spawnPos.x, spawnPos.y, spawnPos.z)) {
                     break spawnLoop;
                 }
             }
             attemptsRemaining--;
         }
-        world.getLevelData().setSpawn(x, y, z);
+        world.getLevelData().setSpawn(spawnPos.x, spawnPos.y, spawnPos.z);
     }
 
     public void getRespawnLocation(World world) {
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/WorldTypeDebug.java b/game/core/src/main/java/net/minecraft/core/world/type/WorldTypeDebug.java
index 2f97744f3..f367fd9b8 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/WorldTypeDebug.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/WorldTypeDebug.java
@@ -1,11 +1,14 @@
 package net.minecraft.core.world.type;
 
 import net.minecraft.core.world.World;
+import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.biome.Biomes;
 import net.minecraft.core.world.biome.provider.BiomeProvider;
 import net.minecraft.core.world.biome.provider.BiomeProviderSingleBiome;
 import net.minecraft.core.world.generate.chunk.ChunkGenerator;
 import net.minecraft.core.world.generate.chunk.debug.ChunkGeneratorDebug;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.Arrays;
 
@@ -26,6 +29,11 @@ public class WorldTypeDebug
         return new BiomeProviderSingleBiome(Biomes.OVERWORLD_PLAINS, 1.0, 1.0, 1.0);
     }
 
+    @Override
+    public @NotNull Biome @NotNull [] allBiomes() {
+        return new Biome[] { Biomes.OVERWORLD_PLAINS };
+    }
+
     @Override
     public ChunkGenerator createChunkGenerator(World world) {
         return new ChunkGeneratorDebug(world);
@@ -37,7 +45,7 @@ public class WorldTypeDebug
     }
 
     @Override
-    public void getInitialSpawnLocation(World world) {
+    public void getInitialSpawnLocation(World world, @Nullable Biome startingBiome) {
         world.getLevelData().setSpawn(0, 1, 0);
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/WorldTypeEmpty.java b/game/core/src/main/java/net/minecraft/core/world/type/WorldTypeEmpty.java
index 5636a9aae..8c4fedf23 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/WorldTypeEmpty.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/WorldTypeEmpty.java
@@ -2,12 +2,15 @@ package net.minecraft.core.world.type;
 
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.World;
+import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.biome.Biomes;
 import net.minecraft.core.world.biome.provider.BiomeProvider;
 import net.minecraft.core.world.biome.provider.BiomeProviderSingleBiome;
 import net.minecraft.core.world.generate.chunk.ChunkGenerator;
 import net.minecraft.core.world.generate.chunk.empty.ChunkGeneratorEmpty;
 import net.minecraft.core.world.weather.Weather;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 public class WorldTypeEmpty
         extends WorldType {
@@ -31,6 +34,11 @@ public class WorldTypeEmpty
         return new BiomeProviderSingleBiome(Biomes.OVERWORLD_PLAINS, 1.0, 1.0, 1.0);
     }
 
+    @Override
+    public @NotNull Biome @NotNull [] allBiomes() {
+        return new Biome[] {Biomes.OVERWORLD_PLAINS } ;
+    }
+
     @Override
     public ChunkGenerator createChunkGenerator(World world) {
         return new ChunkGeneratorEmpty(world);
@@ -42,7 +50,7 @@ public class WorldTypeEmpty
     }
 
     @Override
-    public void getInitialSpawnLocation(World world) {
+    public void getInitialSpawnLocation(World world, @Nullable Biome startingBiome) {
         world.getLevelData().setSpawn(0, 1, 0);
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/drift/WorldTypeDrift.java b/game/core/src/main/java/net/minecraft/core/world/type/drift/WorldTypeDrift.java
index f51eb13b0..c1e850d2f 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/drift/WorldTypeDrift.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/drift/WorldTypeDrift.java
@@ -4,6 +4,7 @@ import net.minecraft.core.Global;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.World;
+import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.biome.Biomes;
 import net.minecraft.core.world.biome.provider.BiomeProvider;
 import net.minecraft.core.world.biome.provider.BiomeProviderSingleBiome;
@@ -12,6 +13,7 @@ import net.minecraft.core.world.generate.chunk.ChunkGenerator;
 import net.minecraft.core.world.generate.chunk.perlin.drift.ChunkGeneratorDrift;
 import net.minecraft.core.world.season.Seasons;
 import net.minecraft.core.world.type.WorldType;
+import org.jetbrains.annotations.NotNull;
 
 public class WorldTypeDrift
         extends WorldType {
@@ -55,6 +57,11 @@ public class WorldTypeDrift
         return new BiomeProviderSingleBiome(Biomes.DRIFT_DRIFT, 0.5, 0.0, 0.0);
     }
 
+    @Override
+    public @NotNull Biome @NotNull [] allBiomes() {
+        return new Biome[] { Biomes.DRIFT_DRIFT };
+    }
+
     @Override
     public ChunkGenerator createChunkGenerator(World world) {
         return new ChunkGeneratorDrift(world);
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/nether/WorldTypeNether.java b/game/core/src/main/java/net/minecraft/core/world/type/nether/WorldTypeNether.java
index c4096ea8e..c77053c8d 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/nether/WorldTypeNether.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/nether/WorldTypeNether.java
@@ -2,13 +2,13 @@ package net.minecraft.core.world.type.nether;
 
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.world.World;
-import net.minecraft.core.world.biome.Biomes;
+import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.biome.provider.BiomeProvider;
 import net.minecraft.core.world.biome.provider.BiomeProviderNether;
-import net.minecraft.core.world.biome.provider.BiomeProviderSingleBiome;
 import net.minecraft.core.world.generate.chunk.ChunkGenerator;
 import net.minecraft.core.world.generate.chunk.perlin.nether.ChunkGeneratorNether;
 import net.minecraft.core.world.type.WorldType;
+import org.jetbrains.annotations.NotNull;
 
 public class WorldTypeNether
         extends WorldType {
@@ -48,6 +48,11 @@ public class WorldTypeNether
         return new BiomeProviderNether(world.getRandomSeed());
     }
 
+    @Override
+    public @NotNull Biome @NotNull [] allBiomes() {
+        return BiomeProviderNether.allBiomes();
+    }
+
     @Override
     public ChunkGenerator createChunkGenerator(World world) {
         return new ChunkGeneratorNether(world);
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeFlat.java b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeFlat.java
index 00f21012b..2e98e3b02 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeFlat.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeFlat.java
@@ -2,11 +2,13 @@ package net.minecraft.core.world.type.overworld;
 
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.world.World;
+import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.biome.Biomes;
 import net.minecraft.core.world.biome.provider.BiomeProvider;
 import net.minecraft.core.world.biome.provider.BiomeProviderSingleBiome;
 import net.minecraft.core.world.generate.chunk.ChunkGenerator;
 import net.minecraft.core.world.generate.chunk.flat.ChunkGeneratorFlat;
+import org.jetbrains.annotations.NotNull;
 
 public class WorldTypeFlat
         extends WorldTypeOverworld {
@@ -19,6 +21,11 @@ public class WorldTypeFlat
         return new BiomeProviderSingleBiome(Biomes.OVERWORLD_PLAINS, 0.5, 0.0, 0.0);
     }
 
+    @Override
+    public @NotNull Biome @NotNull [] allBiomes() {
+        return new Biome[] { Biomes.OVERWORLD_PLAINS };
+    }
+
     @Override
     public ChunkGenerator createChunkGenerator(World world) {
         return new ChunkGeneratorFlat(world);
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworld.java b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworld.java
index f203f4580..d401efce2 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworld.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworld.java
@@ -3,10 +3,9 @@ package net.minecraft.core.world.type.overworld;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.World;
-import net.minecraft.core.world.biome.Biomes;
+import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.biome.provider.BiomeProvider;
 import net.minecraft.core.world.biome.provider.BiomeProviderOverworld;
-import net.minecraft.core.world.biome.provider.BiomeProviderSingleBiome;
 import net.minecraft.core.world.config.season.SeasonConfig;
 import net.minecraft.core.world.generate.chunk.ChunkGenerator;
 import net.minecraft.core.world.generate.chunk.perlin.overworld.ChunkGeneratorOverworld;
@@ -59,6 +58,11 @@ public class WorldTypeOverworld
         return new BiomeProviderOverworld(world.getRandomSeed(), this);
     }
 
+    @Override
+    public @NotNull Biome @NotNull [] allBiomes() {
+        return BiomeProviderOverworld.allBiomes();
+    }
+
     @Override
     public ChunkGenerator createChunkGenerator(World world) {
         return new ChunkGeneratorOverworld(world);
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldB173.java b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldB173.java
index 8736d2c1c..5365694fd 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldB173.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldB173.java
@@ -1,13 +1,12 @@
 package net.minecraft.core.world.type.overworld;
 
 import net.minecraft.core.world.World;
-import net.minecraft.core.world.biome.Biomes;
+import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.biome.provider.BiomeProvider;
 import net.minecraft.core.world.biome.provider.BiomeProviderB173;
-import net.minecraft.core.world.biome.provider.BiomeProviderSingleBiome;
 import net.minecraft.core.world.generate.chunk.ChunkGenerator;
 import net.minecraft.core.world.generate.chunk.perlin.overworld.b173.ChunkGeneratorOverworldB173;
-import net.minecraft.core.world.generate.chunk.perlin.overworld.retro.ChunkGeneratorOverworldRetro;
+import org.jetbrains.annotations.NotNull;
 
 public class WorldTypeOverworldB173
         extends WorldTypeOverworld {
@@ -20,6 +19,11 @@ public class WorldTypeOverworldB173
         return new BiomeProviderB173(world.getRandomSeed());
     }
 
+    @Override
+    public @NotNull Biome @NotNull [] allBiomes() {
+        return BiomeProviderB173.allBiomes();
+    }
+
     @Override
     public ChunkGenerator createChunkGenerator(World world) {
         return new ChunkGeneratorOverworldB173(world);
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldClassic.java b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldClassic.java
index af5134ee1..6e59dace9 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldClassic.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldClassic.java
@@ -1,12 +1,14 @@
 package net.minecraft.core.world.type.overworld;
 
 import net.minecraft.core.world.World;
+import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.biome.Biomes;
 import net.minecraft.core.world.biome.provider.BiomeProvider;
 import net.minecraft.core.world.biome.provider.BiomeProviderSingleBiome;
 import net.minecraft.core.world.generate.chunk.ChunkGenerator;
 import net.minecraft.core.world.generate.chunk.classic.ChunkGeneratorClassic;
 import net.minecraft.core.world.type.WorldType;
+import org.jetbrains.annotations.NotNull;
 
 public class WorldTypeOverworldClassic
         extends WorldTypeOverworld {
@@ -19,6 +21,11 @@ public class WorldTypeOverworldClassic
         return new BiomeProviderSingleBiome(Biomes.OVERWORLD_RETRO, 1.0, 1.0, 1.0);
     }
 
+    @Override
+    public @NotNull Biome @NotNull [] allBiomes() {
+        return new Biome[] { Biomes.OVERWORLD_RETRO };
+    }
+
     @Override
     public ChunkGenerator createChunkGenerator(World world) {
         return new ChunkGeneratorClassic(world);
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldHell.java b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldHell.java
index 771e3419c..faf55ee91 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldHell.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldHell.java
@@ -1,11 +1,13 @@
 package net.minecraft.core.world.type.overworld;
 
 import net.minecraft.core.world.World;
+import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.biome.Biomes;
 import net.minecraft.core.world.biome.provider.BiomeProvider;
 import net.minecraft.core.world.biome.provider.BiomeProviderSingleBiome;
 import net.minecraft.core.world.generate.chunk.ChunkGenerator;
 import net.minecraft.core.world.generate.chunk.perlin.overworld.hell.ChunkGeneratorOverworldHell;
+import org.jetbrains.annotations.NotNull;
 
 public class WorldTypeOverworldHell
         extends WorldTypeOverworld {
@@ -25,6 +27,11 @@ public class WorldTypeOverworldHell
         return new BiomeProviderSingleBiome(Biomes.OVERWORLD_HELL, 1.0, 1.0, 0.0);
     }
 
+    @Override
+    public @NotNull Biome @NotNull [] allBiomes() {
+        return new Biome[] { Biomes.OVERWORLD_HELL };
+    }
+
     @Override
     public ChunkGenerator createChunkGenerator(World world) {
         return new ChunkGeneratorOverworldHell(world);
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldIndev.java b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldIndev.java
index cd0b6da88..12451aa1f 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldIndev.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldIndev.java
@@ -2,6 +2,7 @@ package net.minecraft.core.world.type.overworld;
 
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.world.World;
+import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.biome.Biomes;
 import net.minecraft.core.world.biome.provider.BiomeProvider;
 import net.minecraft.core.world.biome.provider.BiomeProviderSingleBiome;
@@ -10,6 +11,8 @@ import net.minecraft.core.world.generate.chunk.indev.ChunkGeneratorIndev;
 import net.minecraft.core.world.generate.chunk.indev.IndevWorldTheme;
 import net.minecraft.core.world.generate.chunk.indev.IndevWorldType;
 import net.minecraft.core.world.generate.chunk.indev.LevelGenerator;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.Random;
 
@@ -25,7 +28,7 @@ public class WorldTypeOverworldIndev
     }
 
     @Override
-    public void getInitialSpawnLocation(World world) {
+    public void getInitialSpawnLocation(World world, @Nullable Biome startingBiome) {
         int x;
         int y;
         int z;
@@ -54,6 +57,11 @@ public class WorldTypeOverworldIndev
         return new BiomeProviderSingleBiome(Biomes.OVERWORLD_RETRO, 1.0, 1.0, 1.0);
     }
 
+    @Override
+    public @NotNull Biome @NotNull [] allBiomes() {
+        return new Biome[] { Biomes.OVERWORLD_RETRO };
+    }
+
     @Override
     public ChunkGenerator createChunkGenerator(World world) {
         return new ChunkGeneratorIndev(world, 256, getMaxY() + 1, 256, IndevWorldType.ISLAND, IndevWorldTheme.NORMAL);
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldRetro.java b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldRetro.java
index 18e81b245..e91e9ba7b 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldRetro.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldRetro.java
@@ -1,11 +1,13 @@
 package net.minecraft.core.world.type.overworld;
 
 import net.minecraft.core.world.World;
+import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.biome.Biomes;
 import net.minecraft.core.world.biome.provider.BiomeProvider;
 import net.minecraft.core.world.biome.provider.BiomeProviderSingleBiome;
 import net.minecraft.core.world.generate.chunk.ChunkGenerator;
 import net.minecraft.core.world.generate.chunk.perlin.overworld.retro.ChunkGeneratorOverworldRetro;
+import org.jetbrains.annotations.NotNull;
 
 public class WorldTypeOverworldRetro
         extends WorldTypeOverworld {
@@ -18,6 +20,11 @@ public class WorldTypeOverworldRetro
         return new BiomeProviderSingleBiome(Biomes.OVERWORLD_RETRO, 1.0, 1.0, 1.0);
     }
 
+    @Override
+    public @NotNull Biome @NotNull [] allBiomes() {
+        return new Biome[] { Biomes.OVERWORLD_RETRO };
+    }
+
     @Override
     public ChunkGenerator createChunkGenerator(World world) {
         return new ChunkGeneratorOverworldRetro(world);
diff --git a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldSkyblock.java b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldSkyblock.java
index 50f5f00a3..f78a5c4d0 100644
--- a/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldSkyblock.java
+++ b/game/core/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldSkyblock.java
@@ -1,11 +1,14 @@
 package net.minecraft.core.world.type.overworld;
 
 import net.minecraft.core.world.World;
+import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.world.biome.Biomes;
 import net.minecraft.core.world.biome.provider.BiomeProvider;
 import net.minecraft.core.world.biome.provider.BiomeProviderSingleBiome;
 import net.minecraft.core.world.generate.chunk.ChunkGenerator;
 import net.minecraft.core.world.generate.chunk.skyblock.ChunkGeneratorSkyblock;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 public class WorldTypeOverworldSkyblock
         extends WorldTypeOverworld {
@@ -18,6 +21,11 @@ public class WorldTypeOverworldSkyblock
         return new BiomeProviderSingleBiome(Biomes.OVERWORLD_PLAINS, 1.0, 1.0, 1.0);
     }
 
+    @Override
+    public @NotNull Biome @NotNull [] allBiomes() {
+        return new Biome[] { Biomes.OVERWORLD_PLAINS };
+    }
+
     @Override
     public ChunkGenerator createChunkGenerator(World world) {
         return new ChunkGeneratorSkyblock(world);
@@ -29,7 +37,7 @@ public class WorldTypeOverworldSkyblock
     }
 
     @Override
-    public void getInitialSpawnLocation(World world) {
+    public void getInitialSpawnLocation(World world, @Nullable Biome startingBiome) {
         world.getLevelData().setSpawn(0, 66, 0);
     }
 
diff --git a/game/core/src/main/resources/lang/en_US/biomes.lang b/game/core/src/main/resources/lang/en_US/biomes.lang
index 4ccddd7a8..c32253e38 100644
--- a/game/core/src/main/resources/lang/en_US/biomes.lang
+++ b/game/core/src/main/resources/lang/en_US/biomes.lang
@@ -27,4 +27,14 @@ biome.nether.sulfur_pools=Sulfur Pools
 biome.nether.crystal_forest=Crystal Forest
 biome.nether.ash_plains=Ash Plains
 biome.nether.boneyard=Boneyard
-biome.drift.drift=Drift
\ No newline at end of file
+biome.drift.drift=Drift
+
+biome.overworld.legacy.tundra=Beta Tundra
+biome.overworld.legacy.savanna=Beta Savanna
+biome.overworld.legacy.desert=Beta Desert
+biome.overworld.legacy.swampland=Beta Swampland
+biome.overworld.legacy.taiga=Beta Taiga
+biome.overworld.legacy.shrubland=Beta Shrubland
+biome.overworld.legacy.forest=Beta Forest
+biome.overworld.legacy.seasonal_forest=Beta Seasonal Forest
+biome.overworld.legacy.rainforest=Beta Rainforest
\ No newline at end of file
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 4fa3f6de4..c688f7e61 100644
--- a/game/core/src/main/resources/lang/en_US/gui.lang
+++ b/game/core/src/main/resources/lang/en_US/gui.lang
@@ -102,6 +102,13 @@ gui.world_settings.page.game_rules.title=Game Rules
 gui.world_settings.page.world_settings.title=World Settings
 gui.world_settings.page.game_rules.button.on=ON
 gui.world_settings.page.game_rules.button.off=OFF
+gui.world_settings.page.mob_spawning.title=Mob Spawning
+gui.world_settings.page.mob_spawning.button.on=ON
+gui.world_settings.page.mob_spawning.button.off=OFF
+gui.world_settings.page.mob_spawning.hostile=Hostile Spawns
+gui.world_settings.page.mob_spawning.passive=Passive Spawns
+gui.world_settings.label.starting_biome=Starting Biome
+gui.world_settings.page.starting_biome.biome.none=Any
 gui.world_settings.label.select_world_type=Select World Type
 gui.world_settings.label.world_type=World Type
 
@@ -274,6 +281,7 @@ gui.options.page.debug.button.crash.soft=Crash Soft
 gui.options.page.debug.button.crash.hard=Crash Hard
 gui.options.page.debug.button.music.skip=Force Ambient Music
 gui.options.page.debug.button.garbage_collect=Run Garbage Collector
+gui.options.page.debug.button.reload_commands=Reload Commands
 
 gui.options.page.search.title=Search
 
diff --git a/game/core/src/main/resources/lang/en_US/options.lang b/game/core/src/main/resources/lang/en_US/options.lang
index d718e3486..845578e3b 100644
--- a/game/core/src/main/resources/lang/en_US/options.lang
+++ b/game/core/src/main/resources/lang/en_US/options.lang
@@ -49,6 +49,27 @@ options.guiScale.normal=Normal
 options.guiScale.large=Large
 options.advancedOpengl=Advanced OpenGL
 options.treeShadows=Leaf Shadowing
+options.transparencyDepthCheck=Translucent Depth Check
+options.particleQuality=Particle Quality
+options.particleQuality.all=All
+options.particleQuality.reduced=Reduced
+options.particleQuality.none=None
+options.particleCap=Max Particles
+options.particleRenderDistance=Particle Render Distance
+options.particleRenderDistance.default=Default
+options.chunkRebuilds=Chunk Rebuilds Per Frame
+options.frustumCulling=Frustum Culling
+options.entityShadows=Entity Shadows
+options.textOutlineQuality=Text Outline Quality
+options.textOutlineQuality.fast=Fast
+options.textOutlineQuality.fancy=Fancy
+options.cloudQuality=Cloud Quality
+options.cloudQuality.fast=Fast
+options.cloudQuality.fancy=Fancy
+options.leavesQuality=Leaves Quality
+options.leavesQuality.fancy=Fancy
+options.leavesQuality.smart=Smart
+options.leavesQuality.fast=Fast
 options.mods=Texture Packs...
 options.visuals=Visuals...
 options.visualsTitle=Visuals
diff --git a/game/server/src/main/java/net/minecraft/server/entity/player/PlayerServer.java b/game/server/src/main/java/net/minecraft/server/entity/player/PlayerServer.java
index 86abe3c9b..a3ea0fdd1 100644
--- a/game/server/src/main/java/net/minecraft/server/entity/player/PlayerServer.java
+++ b/game/server/src/main/java/net/minecraft/server/entity/player/PlayerServer.java
@@ -678,7 +678,7 @@ public class PlayerServer extends Player implements ContainerListener {
     }
 
     @Override
-	public void addStat(Stat stat, int i)
+	public void addStat(@Nullable Stat stat, int i)
     {
         if (stat == null)
         {
diff --git a/game/server/src/main/java/net/minecraft/server/world/ServerPlayerController.java b/game/server/src/main/java/net/minecraft/server/world/ServerPlayerController.java
index d79dcb677..896e67870 100644
--- a/game/server/src/main/java/net/minecraft/server/world/ServerPlayerController.java
+++ b/game/server/src/main/java/net/minecraft/server/world/ServerPlayerController.java
@@ -214,21 +214,18 @@ public class ServerPlayerController
      * <p>
      * (i.e. throwing a fishing rod or shooting a bow)
      */
-    public boolean useItemStackOnNothing(Player entityplayer, World world, ItemStack itemstack)
+    public boolean useItemStackOnNothing(@NotNull Player player, @NotNull World world, @NotNull ItemStack itemstack)
     {
-        if (!entityplayer.getGamemode().canInteract()) return false;
+        if (!player.getGamemode().canInteract()) return false;
         int i = itemstack.stackSize;
-        ItemStack itemstack1 = itemstack.useItemRightClick(world, entityplayer);
-        if(itemstack1 != itemstack || itemstack1 != null && itemstack1.stackSize != i)
-        {
-            entityplayer.inventory.mainInventory[entityplayer.inventory.getCurrentSlot()] = itemstack1;
-            if(itemstack1.stackSize <= 0)
-            {
-                entityplayer.inventory.mainInventory[entityplayer.inventory.getCurrentSlot()] = null;
+        ItemStack resultStack = itemstack.useItem(world, player);
+        if(resultStack != itemstack || resultStack.stackSize != i) {
+            player.inventory.mainInventory[player.inventory.getCurrentSlot()] = resultStack;
+            if(resultStack == null || resultStack.stackSize <= 0) {
+                player.inventory.mainInventory[player.inventory.getCurrentSlot()] = null;
             }
             return true;
-        } else
-        {
+        } else {
             return false;
         }
     }
diff --git a/game/server/src/main/java/net/minecraft/server/world/WorldServer.java b/game/server/src/main/java/net/minecraft/server/world/WorldServer.java
index 0de63e586..07cb884d0 100644
--- a/game/server/src/main/java/net/minecraft/server/world/WorldServer.java
+++ b/game/server/src/main/java/net/minecraft/server/world/WorldServer.java
@@ -1,27 +1,38 @@
 package net.minecraft.server.world;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
 import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
 import net.minecraft.core.Global;
 import net.minecraft.core.block.entity.TileEntity;
-import net.minecraft.core.world.*;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.net.command.TextFormatting;
+import net.minecraft.core.net.packet.PacketBlockEvent;
+import net.minecraft.core.net.packet.PacketChat;
+import net.minecraft.core.net.packet.PacketCustomPayload;
+import net.minecraft.core.net.packet.PacketEntityEvent;
+import net.minecraft.core.net.packet.PacketEntityTagData;
+import net.minecraft.core.net.packet.PacketExplosion;
+import net.minecraft.core.net.packet.PacketWeatherEffect;
+import net.minecraft.core.net.packet.PacketWeatherStatus;
 import net.minecraft.core.util.helper.MathHelper;
-import net.minecraft.core.net.packet.*;
+import net.minecraft.core.world.Dimension;
+import net.minecraft.core.world.Explosion;
+import net.minecraft.core.world.ExplosionCannonball;
+import net.minecraft.core.world.SpawnerMobs;
+import net.minecraft.core.world.World;
 import net.minecraft.core.world.chunk.IChunkLoader;
 import net.minecraft.core.world.chunk.provider.IChunkProvider;
 import net.minecraft.core.world.pos.TilePosc;
-import net.minecraft.server.world.chunk.provider.ChunkProviderServer;
 import net.minecraft.core.world.save.LevelStorage;
 import net.minecraft.core.world.type.WorldType;
 import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.world.chunk.provider.ChunkProviderServer;
 import org.jetbrains.annotations.NotNull;
 
+import java.util.ArrayList;
+import java.util.List;
+
 public class WorldServer extends World
 {
     public ChunkProviderServer chunkProviderServer;
@@ -33,7 +44,7 @@ public class WorldServer extends World
 
     public WorldServer(MinecraftServer minecraftserver, LevelStorage isavehandler, String name, int dimensionId, WorldType worldType, long seed)
     {
-        super(isavehandler, name, seed, Dimension.getDimensionList().get(dimensionId), worldType);
+        super(isavehandler, name, seed, Dimension.getDimensionList().get(dimensionId), worldType, null);
         entityIntHashMap = new Int2ObjectOpenHashMap<>();
         mcServer = minecraftserver;
         getLevelData().setLastPlayerUUID(null);
