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 aa13993f6..d3cc5142f 100644
--- a/game/client/src/main/java/net/minecraft/client/Minecraft.java
+++ b/game/client/src/main/java/net/minecraft/client/Minecraft.java
@@ -1494,7 +1494,7 @@ public class Minecraft
         }
         Debug.change("textureTick");
         TextureRegistry.blockAtlas.bind();
-        textureManager.updateDynamicTextures(isGamePaused);
+        textureManager.updateDynamicTextures(isGamePaused && currentScreen instanceof ScreenPause);
         Debug.change("misc");
         if(currentScreen == null && thePlayer != null)
         {
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 2abe35c8f..d2cb66ab9 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
@@ -19,14 +19,10 @@ public class ExceptionPopupElement {
         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 forum thread at ")
+        s.append("If you wish to report this, please copy this entire text and post it on the support portal at")
                 .append(TextFormatting.LIGHT_BLUE)
-                .append("https://www.minecraftforum.net/forums/mapping-and-modding-java-edition/minecraft-mods/3106066-better-than-adventure-for-beta-1-7-3-timely")
-                .append(TextFormatting.WHITE).append(", or join the Discord server at ")
-                .append(TextFormatting.LIGHT_BLUE).append("https://betterthanadventure.net/discord")
-                .append(TextFormatting.WHITE).append(" and post it in ")
-                .append(TextFormatting.LIGHT_BLUE).append("#bug-reports")
-                .append(TextFormatting.WHITE).append(".\n\n");
+                .append(" https://bugs.betterthanadventure.net/")
+                .append(TextFormatting.WHITE).append("\n\n");
         try
         {
             s.append(TextFormatting.WHITE).append("Generated ").append((new SimpleDateFormat()).format(new Date())).append("\n\n");
@@ -62,14 +58,10 @@ public class ExceptionPopupElement {
         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 forum thread at ")
+        s.append("If you wish to report this, please copy this entire text and post it on the support portal at")
                 .append(TextFormatting.LIGHT_BLUE)
-                .append("https://www.minecraftforum.net/forums/mapping-and-modding-java-edition/minecraft-mods/3106066-better-than-adventure-for-beta-1-7-3-timely")
-                .append(TextFormatting.WHITE).append(", or join the Discord server at ")
-                .append(TextFormatting.LIGHT_BLUE).append("https://betterthanadventure.net/discord")
-                .append(TextFormatting.WHITE).append(" and post it in ")
-                .append(TextFormatting.LIGHT_BLUE).append("#bug-reports")
-                .append(TextFormatting.WHITE).append(".\n\n");
+                .append(" https://bugs.betterthanadventure.net/")
+                .append(TextFormatting.WHITE).append("\n\n");
         try
         {
             s.append(TextFormatting.WHITE).append("Generated ").append((new SimpleDateFormat()).format(new Date())).append("\n\n");
@@ -107,14 +99,10 @@ public class ExceptionPopupElement {
         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 forum thread at ")
+        s.append("If you wish to report this, please copy this entire text and post it on the support portal at")
                 .append(TextFormatting.LIGHT_BLUE)
-                .append("https://www.minecraftforum.net/forums/mapping-and-modding-java-edition/minecraft-mods/3106066-better-than-adventure-for-beta-1-7-3-timely")
-                .append(TextFormatting.WHITE).append(", or join the Discord server at ")
-                .append(TextFormatting.LIGHT_BLUE).append("https://betterthanadventure.net/discord")
-                .append(TextFormatting.WHITE).append(" and post it in ")
-                .append(TextFormatting.LIGHT_BLUE).append("#bug-reports")
-                .append(TextFormatting.WHITE).append(".\n\n");
+                .append(" https://bugs.betterthanadventure.net/")
+                .append(TextFormatting.WHITE).append("\n\n");
         try
         {
             s.append(TextFormatting.WHITE).append("Generated ").append((new SimpleDateFormat()).format(new Date())).append("\n\n");
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 748b1fce5..dfca17658 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
@@ -183,6 +183,8 @@ public class ScreenMainMenu extends Screen
         ButtonElement debugButton = new ButtonElement(10, width - 8, height - 8, 8, 8, "");
         debugButton.visible = false;
         buttons.add(debugButton);
+        buttons.add(new ButtonElement(11, width / 2 - 104 - 20, i + 72 + 12, 20, 20, "")
+            .setTextures("minecraft:gui/misc/button_support", "minecraft:gui/misc/button_support_highlighted", "minecraft:gui/misc/button_support"));
         if(mc.session == null)
         {
             multiplayerButton.enabled = false;
@@ -197,48 +199,47 @@ public class ScreenMainMenu extends Screen
     @Override
     protected void buttonClicked(ButtonElement button)
     {
-        if(button.id == 0)
-        {
-            mc.displayScreen(new ScreenOptions(this));
-        }
-        if(button.id == 1)
-        {
-            mc.displayScreen(new ScreenSelectWorld(this));
-        }
-        if(button.id == 2)
-        {
-            mc.displayScreen(new ScreenSelectServer(this));
-        }
-        if(button.id == 3)
-        {
-            mc.displayScreen(new ScreenOptions(this, OptionsPages.ASSET_PACKS));
-        }
-        if(button.id == 4)
-        {
-            mc.shutdown();
-        }
-        if(button.id == 5)
-        {
-            mc.displayScreen(new ScreenCredits(this));
-        }
-        if(button.id == 9)
-        {
-            mc.displayScreen(new ScreenOptions(this, OptionsPages.LANGUAGE));
-        }
-        if(button.id == 10){
-            mc.displayScreen(new ScreenOptions(this, OptionsPages.DEBUG));
-        }
-        if (button.id == 6) // Website
-        {
-            UrlHelper.openURL("https://betterthanadventure.net");
-        }
-        if (button.id == 7) // Discord
-        {
-            UrlHelper.openURL("https://betterthanadventure.net/discord");
-        }
-        if (button.id == 8) // YouTube
-        {
-            UrlHelper.openURL("https://www.youtube.com/channel/UC_GT4t8Io87-UTzaGNnsuMg");
+        switch (button.id) {
+            case 0:
+                mc.displayScreen(new ScreenOptions(this));
+                break;
+            case 1:
+                mc.displayScreen(new ScreenSelectWorld(this));
+                break;
+            case 2:
+                mc.displayScreen(new ScreenSelectServer(this));
+                break;
+            case 3:
+                mc.displayScreen(new ScreenOptions(this, OptionsPages.ASSET_PACKS));
+                break;
+            case 4:
+                mc.shutdown();
+                break;
+            case 5:
+                mc.displayScreen(new ScreenCredits(this));
+                break;
+            case 6:
+                // Website
+                UrlHelper.openURL("https://betterthanadventure.net");
+                break;
+            case 7:
+                // Discord
+                UrlHelper.openURL("https://betterthanadventure.net/discord");
+                break;
+            case 8:
+                // YouTube
+                UrlHelper.openURL("https://www.youtube.com/channel/UC_GT4t8Io87-UTzaGNnsuMg");
+                break;
+            case 11:
+                // Support
+                UrlHelper.openURL("https://bugs.betterthanadventure.net/");
+                break;
+            case 9:
+                mc.displayScreen(new ScreenOptions(this, OptionsPages.LANGUAGE));
+                break;
+            case 10:
+                mc.displayScreen(new ScreenOptions(this, OptionsPages.DEBUG));
+                break;
         }
     }
 
diff --git a/game/client/src/main/java/net/minecraft/client/gui/ScreenPause.java b/game/client/src/main/java/net/minecraft/client/gui/ScreenPause.java
index 733ace42f..9e4266709 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/ScreenPause.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/ScreenPause.java
@@ -6,6 +6,7 @@ import net.minecraft.client.gui.guidebook.ScreenGuidebook;
 import net.minecraft.client.gui.guidebook.search.GuidebookPageSearch;
 import net.minecraft.client.gui.options.ScreenOptions;
 import net.minecraft.client.gui.options.data.OptionsPages;
+import net.minecraft.client.util.helper.UrlHelper;
 import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.data.registry.recipe.SearchQuery;
 import net.minecraft.core.util.helper.MathHelper;
@@ -48,52 +49,52 @@ public class ScreenPause extends Screen
         ButtonElement debugButton = new ButtonElement(9, width - 8, height - 8, 8, 8, "");
         debugButton.visible = false;
         buttons.add(debugButton);
+        buttons.add(new ButtonElement(10, width / 2 - 100 - 24, height / 4 + 120 + byte0, 20, 20, "")
+            .setTextures("minecraft:gui/misc/button_support", "minecraft:gui/misc/button_support_highlighted", "minecraft:gui/misc/button_support"));
     }
 
     @Override
 	protected void buttonClicked(ButtonElement button)
     {
-        if(button.id == 0)
-        {
-            mc.displayScreen(new ScreenOptions(this));
-        }
-        if(button.id == 1)
-        {
-            mc.statsCounter.add(StatList.leaveGameStat, 1);
-            if(mc.isMultiplayerWorld())
-            {
-                mc.currentWorld.sendQuittingDisconnectingPacket();
-                Registries.RECIPES = Registries.RECIPES_LOCAL_COPY;
-                GuidebookPageSearch.searchField.setText("");
-                GuidebookPageManager.searchQuery = SearchQuery.resolve(GuidebookPageSearch.searchField.getText());
-                ScreenGuidebook.getPageManager().updatePages();
-            }
-            mc.changeWorld(null);
-            mc.displayScreen(new ScreenMainMenu());
-        }
-        if(button.id == 4)
-        {
-            mc.displayScreen(null);
-            mc.setIngameFocus();
-            
-            //Cancel A press so you dont jump because you hold the jump button
-            if(mc.inputType == InputType.CONTROLLER) mc.controllerInput.buttonA.cancelButtonPress();
-            
-        }
-        if(button.id == 5)
-        {
-            mc.displayScreen(new ScreenAchievements(this, mc.statsCounter));
-        }
-        if(button.id == 6)
-        {
-            mc.displayScreen(new ScreenStats(this, mc.statsCounter));
-        }
-        if (button.id == 7)
-        {
-            mc.displayScreen(new ScreenPhotoMode());
-        }
-        if(button.id == 9){
-            mc.displayScreen(new ScreenOptions(this, OptionsPages.DEBUG));
+        switch (button.id) {
+            case 0:
+                mc.displayScreen(new ScreenOptions(this));
+                break;
+            case 1:
+                mc.statsCounter.add(StatList.leaveGameStat, 1);
+                if (mc.isMultiplayerWorld()) {
+                    mc.currentWorld.sendQuittingDisconnectingPacket();
+                    Registries.RECIPES = Registries.RECIPES_LOCAL_COPY;
+                    GuidebookPageSearch.searchField.setText("");
+                    GuidebookPageManager.searchQuery = SearchQuery.resolve(GuidebookPageSearch.searchField.getText());
+                    ScreenGuidebook.getPageManager().updatePages();
+                }
+                mc.changeWorld(null);
+                mc.displayScreen(new ScreenMainMenu());
+                break;
+            case 4:
+                mc.displayScreen(null);
+                mc.setIngameFocus();
+
+                //Cancel A press so you dont jump because you hold the jump button
+                if (mc.inputType == InputType.CONTROLLER) mc.controllerInput.buttonA.cancelButtonPress();
+
+                break;
+            case 5:
+                mc.displayScreen(new ScreenAchievements(this, mc.statsCounter));
+                break;
+            case 6:
+                mc.displayScreen(new ScreenStats(this, mc.statsCounter));
+                break;
+            case 7:
+                mc.displayScreen(new ScreenPhotoMode());
+                break;
+            case 9:
+                mc.displayScreen(new ScreenOptions(this, OptionsPages.DEBUG));
+                break;
+            case 10:
+                UrlHelper.openURL("https://bugs.betterthanadventure.net/");
+                break;
         }
     }
 
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 58cf00879..b864a15ba 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
@@ -220,7 +220,9 @@ public class TooltipElement extends Gui
 
 			if(showDescription) {
 				text.append('\n').append(formatDescription(itemStack.getItemDescription(), 16));
-			}
+			} else {
+                text.append('\n').append(formatDescription(trans.translateKeyAndFormat("gui.tooltip.prompt.description", mc.gameSettings.keyDescription.getKeyName()), 16));
+            }
 
 			if(slot instanceof SlotResult) {
 				if(shiftPressed && !ctrlPressed) {
diff --git a/game/client/src/main/java/net/minecraft/client/gui/achievements/ScreenAchievements.java b/game/client/src/main/java/net/minecraft/client/gui/achievements/ScreenAchievements.java
index e0eeb60bc..3e5d3f2ac 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/achievements/ScreenAchievements.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/achievements/ScreenAchievements.java
@@ -626,13 +626,8 @@ public class ScreenAchievements extends Screen
                             shadowScale *= 0.5f;
                         }
                         GL11.glColor4f(brightness * shadowScale, brightness * shadowScale, brightness * shadowScale, 1.0F);
-                        drawTexturedModalRectDouble(
-                            iconLeft, iconTop,
-                            fore.iconX, fore.iconY,
-                            iconWidth, iconHeight,
-                            fore.width, fore.height,
-                            fore.parentAtlas.getInverseWidth(),
-                            fore.parentAtlas.getInverseHeight());
+                        final double epsilon = 0.05;
+                        drawGuiIconDouble(iconLeft - epsilon, iconTop - epsilon, iconWidth + epsilon * 2, iconHeight + epsilon * 2, fore);
                     }
 
                     GL11.glDisable(GL11.GL_TEXTURE_2D);
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 0e275291a..12ac320ad 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
@@ -112,7 +112,7 @@ public abstract class ScreenContainerAbstract extends Screen
 		GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
 		if (inventoryplayer.getHeldItemStack() == null && slot != null && slot.hasItem())
 		{
-			boolean showDescription = Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL) || mc.gameSettings.alwaysShowDescriptions.value;
+			boolean showDescription = mc.gameSettings.alwaysShowDescriptions.value || mc.gameSettings.keyDescription.isPressed();
 			String str = tooltipElement.getTooltipText(slot.getItemStack(), showDescription, slot);
 			if(str.length() > 0)
 			{
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 dc98a41f3..350e0bdc3 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
@@ -195,7 +195,7 @@ public class RecipePageCrafting
             GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
             if (mouseOverSlot != null && mouseOverSlot.hasItem())
             {
-                boolean showDescription = Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL) || mc.gameSettings.alwaysShowDescriptions.value;
+                boolean showDescription = mc.gameSettings.alwaysShowDescriptions.value || mc.gameSettings.keyDescription.isPressed();
                 String str = tooltipElement.getTooltipText(mouseOverSlot.getItemStack(), showDescription, mouseOverSlot);
                 if(!str.isEmpty())
                 {
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 eb46eeb9a..af98df2dd 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
@@ -280,7 +280,7 @@ public class GuidebookPageMob
             GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
             if (mouseOverSlot != null && mouseOverSlot.hasItem())
             {
-                boolean showDescription = Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL) || mc.gameSettings.alwaysShowDescriptions.value;
+                boolean showDescription = mc.gameSettings.alwaysShowDescriptions.value || mc.gameSettings.keyDescription.isPressed();
                 String str = tooltipElement.getTooltipText(mouseOverSlot.getItemStack(), showDescription, mouseOverSlot);
                 if(!str.isEmpty())
                 {
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 07271ee38..34f11ecfe 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
@@ -150,7 +150,7 @@ public class RecipePageBlastSmelting
             GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
             if (mouseOverSlot != null && mouseOverSlot.hasItem())
             {
-                boolean showDescription = Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL) || mc.gameSettings.alwaysShowDescriptions.value;
+                boolean showDescription = mc.gameSettings.alwaysShowDescriptions.value || mc.gameSettings.keyDescription.isPressed();
                 String str = tooltipElement.getTooltipText(mouseOverSlot.getItemStack(), showDescription, mouseOverSlot);
                 if(!str.isEmpty())
                 {
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 d90e32c14..5639bf0b5 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
@@ -150,7 +150,7 @@ public class RecipePageSmelting
             GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
             if (mouseOverSlot != null && mouseOverSlot.hasItem())
             {
-                boolean showDescription = Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL) || mc.gameSettings.alwaysShowDescriptions.value;
+                boolean showDescription = mc.gameSettings.alwaysShowDescriptions.value || mc.gameSettings.keyDescription.isPressed();
                 String str = tooltipElement.getTooltipText(mouseOverSlot.getItemStack(), showDescription, mouseOverSlot);
                 if(!str.isEmpty())
                 {
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 7cdf01baa..1d5fbceae 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
@@ -199,7 +199,7 @@ public class RecipePageTrommel
             GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
             if (mouseOverSlot != null && mouseOverSlot.hasItem())
             {
-                boolean showDescription = Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL) || mc.gameSettings.alwaysShowDescriptions.value;
+                boolean showDescription = mc.gameSettings.alwaysShowDescriptions.value || mc.gameSettings.keyDescription.isPressed();
                 String str = tooltipElement.getTooltipText(mouseOverSlot.getItemStack(), showDescription, mouseOverSlot);
                 if(!str.isEmpty())
                 {
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 30175d64b..e0960ab83 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
@@ -140,9 +140,9 @@ public class HudComponentHotbar
         gui.drawGuiIcon(x + 5, y, 182, 22, TextureRegistry.getTexture("minecraft:gui/hud/hotbar"));
 
         // Render hotbar switcher and dots
-        IconCoordinate coordinate = TextureRegistry.getTexture("minecraft:gui/hud/hotbar_selector");
-        gui.drawIconTexture(x, y,       x + 6, y + 22, 0, 0, 6, 22, coordinate);
-        gui.drawIconTexture(x, y + 15,  x + 6, y + 15 + 5, 6, 5, 12, 10, coordinate);
+        final int selectedHotbar = 3;
+        IconCoordinate coordinate = TextureRegistry.getTexture("minecraft:gui/hud/hotbar_selector" + selectedHotbar);
+        gui.drawGuiIcon(x, y, 6, 22, coordinate);
 
         // Render selector
         gui.drawGuiIcon((x + 4), y - 1, 24, 24, TextureRegistry.getTexture("minecraft:gui/hud/hotbar_selection"));
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 862981d41..2cb9e6c18 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
@@ -17,12 +17,12 @@ import net.minecraft.client.sound.SoundEngine;
 import net.minecraft.client.util.helper.FileOpener;
 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;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.item.Items;
-import net.minecraft.core.util.helper.Utils;
 import org.useless.seedviewer.SeedViewerMain;
 import paulscode.sound.SoundSystem;
 
@@ -173,7 +173,7 @@ public abstract class OptionsPages
             )
         );
 
-        CONTROLS = register(new OptionsPage("gui.options.page.controls.title", new ItemStack(Items.BOOK))
+        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))
@@ -221,6 +221,7 @@ public abstract class OptionsPages
                 .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))
@@ -399,7 +400,9 @@ public abstract class OptionsPages
                     throw new RuntimeException("Test Soft Exception");
                 }))
                 .withComponent(new ShortcutComponent("gui.options.page.debug.button.crash.hard", () -> {
-                    throw new RuntimeErrorException(new Error(), "Test Hard Exception");
+                    Minecraft.getMinecraft().gameWindow.displayCrashReport(new UnexpectedThrowable("Test Hard Exception", new Error()), -1);
+                    Minecraft.getMinecraft().hasCrashed = true;
+                    throw new Error();
                 }))
             );
     }
diff --git a/game/client/src/main/java/net/minecraft/client/gui/toasts/GuiElementToastsHud.java b/game/client/src/main/java/net/minecraft/client/gui/toasts/GuiElementToastsHud.java
index d9313b0ba..dce1e1dbe 100644
--- a/game/client/src/main/java/net/minecraft/client/gui/toasts/GuiElementToastsHud.java
+++ b/game/client/src/main/java/net/minecraft/client/gui/toasts/GuiElementToastsHud.java
@@ -127,6 +127,7 @@ public class GuiElementToastsHud extends Gui {
         GL11.glDepthMask(false);
 
         int yOff = 0;
+        GL11.glEnable(GL11.GL_BLEND);
         for (ToastEntry entry : activeEntries){ // Render all entries
             long duration = System.currentTimeMillis() - entry.startTime;
 
@@ -153,6 +154,7 @@ public class GuiElementToastsHud extends Gui {
             Scissor.disable();
             yOff += TOAST_HEIGHT + toastTop;
         }
+        GL11.glDisable(GL11.GL_BLEND);
 
         GL11.glDisable(GL12.GL_RESCALE_NORMAL);
         Lighting.disable();
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 12f080b50..b1c14b98e 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
@@ -298,6 +298,19 @@ public class PacketHandlerClient extends PacketHandler
         }
     }
 
+    @Override
+    public void handleEntityFling(final PacketEntityFling packetEntityFling) {
+        final Entity entity = getEntityByID(packetEntityFling.entityId);
+        if (entity != null) {
+            entity.pushesThisTick = packetEntityFling.pushesTick;
+            entity.fallDistance = 0;
+            entity.xd = packetEntityFling.xd;
+            entity.yd = packetEntityFling.yd;
+            entity.zd = packetEntityFling.zd;
+            entity.pushTime = packetEntityFling.pushTime;
+        }
+    }
+
     @Override
     public void handleEntityMetadata(PacketSetEntityData setEntityDataPacket)
     {
@@ -309,31 +322,34 @@ public class PacketHandlerClient extends PacketHandler
     }
 
     @Override
-    public void handleNamedEntitySpawn(PacketAddPlayer addPlayerPacket)
+    public void handleNamedEntitySpawn(final PacketAddPlayer addPlayerPacket)
     {
-        double d = (double) addPlayerPacket.xPosition / 32D;
-        double d1 = (double) addPlayerPacket.yPosition / 32D;
-        double d2 = (double) addPlayerPacket.zPosition / 32D;
-        float f = (float) (addPlayerPacket.rotation * 360) / 256F;
-        float f1 = (float) (addPlayerPacket.pitch * 360) / 256F;
-        PlayerRemote playerRemote = new PlayerRemote(mc.currentWorld, addPlayerPacket.name, addPlayerPacket.uuid);
+        final double x = (double) addPlayerPacket.xPosition / 32D;
+        final double y = (double) addPlayerPacket.yPosition / 32D;
+        final double z = (double) addPlayerPacket.zPosition / 32D;
+        final float yRot = (float) (addPlayerPacket.rotation * 360) / 256F;
+        final float xRot = (float) (addPlayerPacket.pitch * 360) / 256F;
+        final PlayerRemote playerRemote = new PlayerRemote(this.mc.currentWorld, addPlayerPacket.name, addPlayerPacket.uuid);
         playerRemote.playerConfig.config = addPlayerPacket.playerConfig;
         playerRemote.xo = playerRemote.serverPosX = addPlayerPacket.xPosition;
         playerRemote.yo = playerRemote.serverPosY = addPlayerPacket.yPosition;
         playerRemote.zo = playerRemote.serverPosZ = addPlayerPacket.zPosition;
-        int i = addPlayerPacket.currentItem;
-        if (i == 0)
+        final int itemId = addPlayerPacket.currentItem;
+        if (itemId == 0)
         {
             playerRemote.inventory.mainInventory[playerRemote.inventory.getCurrentItemIndex()] = null;
         }
         else
         {
-            playerRemote.inventory.mainInventory[playerRemote.inventory.getCurrentItemIndex()] = new ItemStack(i, 1, 0);
+            playerRemote.inventory.mainInventory[playerRemote.inventory.getCurrentItemIndex()] = new ItemStack(itemId, 1, 0);
         }
-        playerRemote.absMoveTo(d, d1, d2, f, f1);
-        worldClientMP.addEntityToWorld(addPlayerPacket.entityId, playerRemote);
+        playerRemote.absMoveTo(x, y, z, yRot, xRot);
+        this.worldClientMP.addEntityToWorld(addPlayerPacket.entityId, playerRemote);
         playerRemote.nickname = StringUtils.substring(addPlayerPacket.nickname, 0, 32);
         playerRemote.chatColor = addPlayerPacket.chatColor;
+        if (addPlayerPacket.gamemode >= 0 && addPlayerPacket.gamemode < Gamemode.gamemodesList.length) {
+            playerRemote.setGamemode(Gamemode.gamemodesList[addPlayerPacket.gamemode]);
+        }
 
         playerRemote.setHeldObject(addPlayerPacket.heldObjectTag == null ? null : ICarriable.createAndLoadCarriable(playerRemote, addPlayerPacket.heldObjectTag));
     }
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 0cbbfd45d..1f406c12f 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
@@ -206,6 +206,7 @@ public class GameSettings {
 	public KeyBinding keySneak = new KeyBinding("key.sneak").setDefault(InputDevice.keyboard, KEY_LSHIFT);
 	public KeyBinding keyFly = new KeyBinding("key.fly").setDefault(InputDevice.keyboard, KEY_LCONTROL);
 	public KeyBinding keyGuidebook = new KeyBinding("key.guidebook").setDefault(InputDevice.keyboard, KEY_R);
+	public KeyBinding keyDescription = new KeyBinding("key.description").setDefault(InputDevice.keyboard, KEY_LCONTROL);
 	public KeyBinding keyShowRecipe = new KeyBinding("key.showRecipe").setDefault(InputDevice.keyboard, KEY_R);
 	public KeyBinding keyShowUsage = new KeyBinding("key.showUsage").setDefault(InputDevice.keyboard, KEY_U);
 	public KeyBinding keyHotBarLeft = new KeyBinding("key.hotbar.left").setDefault(InputDevice.keyboard, KEY_COMMA);
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 581ad42be..6d5f29970 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
@@ -191,6 +191,10 @@ public class KeyBinding {
 		String keyName = inputDevice.getKeyName(keyCode);
 		if(keyName == null) {
 			keyName = String.valueOf(keyCode);
+		} else if ("LCONTROL".equals(keyName)) {
+			keyName = "LCTRL";
+		} else if ("RCONTROL".equals(keyName)) {
+			keyName = "RCTRL";
 		}
 		return keyName;
 	}
diff --git a/game/client/src/main/java/net/minecraft/client/render/Lighting.java b/game/client/src/main/java/net/minecraft/client/render/Lighting.java
index 8afaf7acc..9585a75f5 100644
--- a/game/client/src/main/java/net/minecraft/client/render/Lighting.java
+++ b/game/client/src/main/java/net/minecraft/client/render/Lighting.java
@@ -13,10 +13,10 @@ public class Lighting {
 	}
 
 	public static void disable() {
-		glDisable(2896 /* GL_LIGHTING */);
-		glDisable(16384 /* GL_LIGHT0 */);
-		glDisable(16385 /* GL_LIGHT1 */);
-		glDisable(2903 /* GL_COLOR_MATERIAL */);
+		glDisable(GL_LIGHTING);
+		glDisable(GL_LIGHT0);
+		glDisable(GL_LIGHT1);
+		glDisable(GL_COLOR_MATERIAL);
 	}
 
 	public static void enableInventoryLight() {
diff --git a/game/client/src/main/java/net/minecraft/client/render/PanelCrashReport.java b/game/client/src/main/java/net/minecraft/client/render/PanelCrashReport.java
index 02e136fef..e9cbced5f 100644
--- a/game/client/src/main/java/net/minecraft/client/render/PanelCrashReport.java
+++ b/game/client/src/main/java/net/minecraft/client/render/PanelCrashReport.java
@@ -80,7 +80,7 @@ public class PanelCrashReport extends Panel {
 			finalCrashReport += "\n";
 			finalCrashReport += "\nMinecraft has stopped running because it encountered a problem.";
 			finalCrashReport += "\n";
-			finalCrashReport += "\nIf you wish to report this, please copy this entire text and post it on the forum thread at https://www.minecraftforum.net/forums/mapping-and-modding-java-edition/minecraft-mods/3106066-better-than-adventure-for-beta-1-7-3-timely, or join the Discord server at https://betterthanadventure.net/discord and post it in #bug-reports.";
+			finalCrashReport += "\nIf you wish to report this, please copy this entire text and post it on the support portal at https://bugs.betterthanadventure.net/";
 			finalCrashReport += "\nPlease include a description of what you did when the error occured.";
 		}
 		finalCrashReport += "\n";
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 f1d1184fc..882c08654 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
@@ -27,6 +27,11 @@ import org.useless.dragonfly.models.entity.StaticEntityModel;
 
 import java.util.UUID;
 
+import static org.lwjgl.opengl.GL11.GL_COLOR_MATERIAL;
+import static org.lwjgl.opengl.GL11.GL_LIGHT0;
+import static org.lwjgl.opengl.GL11.GL_LIGHT1;
+import static org.lwjgl.opengl.GL11.GL_LIGHTING;
+
 public class MobRendererPlayer extends MobRendererBipedArmored<Player>
 {
     private BlocksContainer container = null;
@@ -109,8 +114,11 @@ public class MobRendererPlayer extends MobRendererBipedArmored<Player>
                 carriedBlock.entity.worldObj = null;
             }
 
-            Lighting.enableLight();
             GL11.glPopMatrix();
+            GL11.glEnable(GL_LIGHTING);
+            GL11.glEnable(GL_LIGHT0);
+            GL11.glEnable(GL_LIGHT1);
+            GL11.glEnable(GL_COLOR_MATERIAL);
         }
     }
     @Override
diff --git a/game/client/src/main/java/net/minecraft/client/sound/SoundRepository.java b/game/client/src/main/java/net/minecraft/client/sound/SoundRepository.java
index 0b78e845b..ead8db828 100644
--- a/game/client/src/main/java/net/minecraft/client/sound/SoundRepository.java
+++ b/game/client/src/main/java/net/minecraft/client/sound/SoundRepository.java
@@ -11,6 +11,7 @@ import java.util.*;
 public class SoundRepository extends Registry<NamedSoundRepository> {
     protected static Minecraft mc = null;
     public static SoundRepository SOUNDS = null;
+    public static Set<String> namespaces = new HashSet<>();
 
     public static final Set<String> allKeys = new HashSet<>();
 
@@ -18,11 +19,10 @@ public class SoundRepository extends Registry<NamedSoundRepository> {
     public Set<NamespaceID> cachedEntryErrors = new HashSet<>();
 
     public SoundRepository() {
-        registerNamespace("minecraft");
-    }
-
-    public void registerNamespace(@NotNull String namespace) {
-        register(namespace, new NamedSoundRepository(namespace));
+        super();
+        for (final String s : namespaces) {
+            register(s, new NamedSoundRepository(s));
+        }
     }
 
     public @Nullable SoundEvent getSoundEvent(@Nullable String key) {
@@ -116,4 +116,14 @@ public class SoundRepository extends Registry<NamedSoundRepository> {
         SOUNDS = new SoundRepository();
     }
 
+    public static void registerNamespace(final @NotNull String namespace) {
+        if (namespaces.add(namespace) && SOUNDS != null) {
+            SOUNDS.register(namespace, new NamedSoundRepository(namespace));
+        }
+    }
+
+    static {
+        registerNamespace("minecraft");
+    }
+
 }
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/chest/planks/left_back.png b/game/client/src/main/resources/assets/minecraft/textures/block/chest/planks/left_back.png
index c32cd5ff4..8ff85af6b 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/chest/planks/left_back.png and b/game/client/src/main/resources/assets/minecraft/textures/block/chest/planks/left_back.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/block/chest/planks/left_front.png b/game/client/src/main/resources/assets/minecraft/textures/block/chest/planks/left_front.png
index 57c8074ec..758736632 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/block/chest/planks/left_front.png and b/game/client/src/main/resources/assets/minecraft/textures/block/chest/planks/left_front.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sprites/misc/button_support.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sprites/misc/button_support.png
new file mode 100644
index 000000000..8107ac4d6
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/gui/sprites/misc/button_support.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sprites/misc/button_support.xcf b/game/client/src/main/resources/assets/minecraft/textures/gui/sprites/misc/button_support.xcf
new file mode 100644
index 000000000..9d2148260
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/gui/sprites/misc/button_support.xcf differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/gui/sprites/misc/button_support_highlighted.png b/game/client/src/main/resources/assets/minecraft/textures/gui/sprites/misc/button_support_highlighted.png
new file mode 100644
index 000000000..eff1442e5
Binary files /dev/null and b/game/client/src/main/resources/assets/minecraft/textures/gui/sprites/misc/button_support_highlighted.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/item/ore_raw_gold.png b/game/client/src/main/resources/assets/minecraft/textures/item/ore_raw_gold.png
index ec92c8031..a28502f0e 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/item/ore_raw_gold.png and b/game/client/src/main/resources/assets/minecraft/textures/item/ore_raw_gold.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/item/ore_raw_iron.png b/game/client/src/main/resources/assets/minecraft/textures/item/ore_raw_iron.png
index 4fe7828d7..d700f412b 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/item/ore_raw_iron.png and b/game/client/src/main/resources/assets/minecraft/textures/item/ore_raw_iron.png differ
diff --git a/game/client/src/main/resources/assets/minecraft/textures/item/rope.png b/game/client/src/main/resources/assets/minecraft/textures/item/rope.png
index d9da72221..ae0b5425d 100644
Binary files a/game/client/src/main/resources/assets/minecraft/textures/item/rope.png and b/game/client/src/main/resources/assets/minecraft/textures/item/rope.png differ
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRail.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRail.java
index 5b3a4ee52..d97bc0ea8 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicRail.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicRail.java
@@ -241,9 +241,9 @@ public class BlockLogicRail extends BlockLogic {
             this.y = y;
             this.z = z;
             Block<?> block = world.getBlock(x, y, z);
-            int meta = world.getBlockMetadata(x, y, z);
-
             isPoweredRail = (block != null && block.getLogic() instanceof BlockLogicRail) && ((BlockLogicRail) block.getLogic()).isPowered;
+            int meta = world.getBlockMetadata(x, y, z) & (isPoweredRail ? MASK_DIRECTION : 0b1111_1111);
+
 
             setConnections(RailDirection.getFromMeta(meta));
         }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlab.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlab.java
index d7bcbc3b0..e230cf2a4 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlab.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicSlab.java
@@ -87,28 +87,6 @@ public class BlockLogicSlab extends BlockLogic
         return (meta & 0x3) != 0;
     }
 
-    @Override
-    public ItemStack @Nullable [] getBreakResult(World world, EnumDropCause dropCause, int x, int y, int z, int meta, TileEntity tileEntity)
-    {
-        final ItemStack @Nullable [] result = dropCause != EnumDropCause.IMPROPER_TOOL ? new ItemStack[] { new ItemStack(this.block) } : null;
-
-        if (result != null)
-        {
-            for (ItemStack stack : result)
-            {
-                if (stack.itemID == modelBlock.id())
-                {
-                    stack.setMetadata(meta & 0xF0);
-                    stack.itemID = this.id();
-                    if ((meta & 0x3) == 1 && dropCause != EnumDropCause.PICK_BLOCK) stack.stackSize = 2;
-                    else stack.stackSize = 1;
-                }
-            }
-        }
-
-        return result;
-    }
-
     @Override
     public ItemStack[] getBreakResult(World world, EnumDropCause dropCause, int meta, TileEntity tileEntity)
     {
@@ -118,13 +96,10 @@ public class BlockLogicSlab extends BlockLogic
         {
             for (ItemStack stack : result)
             {
-                if (stack.itemID == modelBlock.id())
-                {
-                    stack.setMetadata(meta & 0xF0);
-                    stack.itemID = this.id();
-                    if ((meta & 0x3) == 1 && dropCause != EnumDropCause.PICK_BLOCK) stack.stackSize = 2;
-                    else stack.stackSize = 1;
-                }
+                stack.setMetadata(meta & 0xF0);
+                stack.itemID = this.id();
+                if ((meta & 0b11) == 1 && dropCause != EnumDropCause.PICK_BLOCK) stack.stackSize = 2;
+                else stack.stackSize = 1;
             }
         }
 
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairs.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairs.java
index a8d6700db..df021c4f0 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairs.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicStairs.java
@@ -149,25 +149,6 @@ public class BlockLogicStairs extends BlockLogic
         }
     }
 
-    @Override
-    public ItemStack @Nullable [] getBreakResult(World world, EnumDropCause dropCause, int x, int y, int z, int meta, TileEntity tileEntity)
-    {
-        final ItemStack @Nullable [] result = dropCause != EnumDropCause.IMPROPER_TOOL ? new ItemStack[] { new ItemStack(this.block) } : null;
-
-        if (result != null)
-        {
-            for (ItemStack stack : result)
-            {
-                if (stack.itemID == modelBlock.id())
-                {
-                    stack.setMetadata(meta & 0xF0);
-                    stack.itemID = this.id();
-                }
-            }
-        }
-
-        return result;
-    }
 
     @Override
     public ItemStack @Nullable [] getBreakResult(World world, EnumDropCause dropCause, int meta, TileEntity tileEntity)
@@ -178,11 +159,8 @@ public class BlockLogicStairs extends BlockLogic
         {
             for (ItemStack stack : result)
             {
-                if (stack.itemID == modelBlock.id())
-                {
-                    stack.setMetadata(meta & 0xF0);
-                    stack.itemID = this.id();
-                }
+                stack.setMetadata(meta & 0xF0);
+                stack.itemID = this.id();
             }
         }
 
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 f48bd507d..28381d39e 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
@@ -403,10 +403,10 @@ public final class Blocks {
         .withTags(BlockTags.MINEABLE_BY_SHEARS);
     public static final Block<?> PUMICE_DRY = register("pumice.dry", "minecraft:block/pumice_dry", 232, (b) -> new BlockLogicPumice(b, false))
         .withSound(BlockSounds.STONE).withHardness(0.6F).withOverrideColor(MaterialColor.fire)
-        .withTags(BlockTags.MINEABLE_BY_SHEARS);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
     public static final Block<?> PUMICE_WET = register("pumice.wet", "minecraft:block/pumice_wet", 233, (b) -> new BlockLogicPumice(b, true))
         .withSound(BlockSounds.STONE).withHardness(1.0F).withLightEmission(0.625F).withOverrideColor(MaterialColor.fire)
-        .withTags(BlockTags.MINEABLE_BY_SHEARS);
+        .withTags(BlockTags.MINEABLE_BY_PICKAXE);
 
     public static final Block<?> MOSS_STONE = register("moss.stone", "minecraft:block/moss_stone", 240, (b) -> new BlockLogicMoss(b, Blocks.STONE))
         .withSound(BlockSounds.STONE).withHardness(1.5F).withBlastResistance(10F)
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 9f948e462..342f01bd1 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
@@ -6,6 +6,7 @@ import java.util.Random;
 import net.minecraft.core.block.BlockLogicFluid;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.entity.vehicle.EntityBoat;
+import net.minecraft.core.block.piston.BlockLogicPistonHead;
 import net.minecraft.core.util.collection.NamespaceID;
 import net.minecraft.core.util.helper.DyeColor;
 import net.minecraft.core.world.Dimension;
@@ -729,28 +730,25 @@ public abstract class Entity
         return true;
     }
 
-    protected void checkFallDamage(double yd, boolean onGround)
+    protected void checkFallDamage(final double yd, final boolean onGround)
     {
-        if (onGround)
+        if (this.vehicle != null || this.noPhysics) {
+            this.fallDistance = 0;
+        }
+        else if (onGround)
         {
-            if(fallDistance > 0.0F)
+            if(this.fallDistance > 0.0F)
             {
-                causeFallDamage(fallDistance);
-                fallDistance = 0.0F;
+                causeFallDamage(this.fallDistance);
+                this.fallDistance = 0.0F;
             }
         }
-        else if (isFalling())
+        else if (yd < 0.0D)
         {
-            fallDistance -= yd;
-        } else {
-            fallDistance = 0;
+            this.fallDistance -= (float) yd;
         }
     }
 
-    public boolean isFalling() {
-        return !onGround && !noPhysics && yd < 0 && vehicle == null;
-    }
-
     public AABB getBb()
     {
         return null;
@@ -861,15 +859,42 @@ public abstract class Entity
     }
     
     public int getLightmapCoord(float partialTick) {
-        int blockX = MathHelper.floor(x);
-        double d = (bb.maxY - bb.minY) * 0.66D;
-    	int blockY = MathHelper.floor((y - (double) heightOffset) + d);
-    	int blockZ = MathHelper.floor(z);
-    	
-    	int skylight = world.getSavedLightValue(LightLayer.Sky, blockX, blockY, blockZ);
-    	int blocklight = world.getSavedLightValue(LightLayer.Block, blockX, blockY, blockZ);
+        final int blockX = MathHelper.floor(this.x);
+    	final int blockY = MathHelper.floor(this.y - this.heightOffset + this.ySlideOffset + this.bbHeight * 0.66D);
+    	final int blockZ = MathHelper.floor(this.z);
+
+        final int skylight;
+        final int blocklight;
+        if(this.world.getBlockLitInteriorSurface(blockX, blockY, blockZ))
+        {
+                  int bU = this.world.getSavedLightValue(LightLayer.Block, blockX,      blockY + 1, blockZ);
+            final int bW = this.world.getSavedLightValue(LightLayer.Block, blockX + 1,  blockY,     blockZ);
+            final int bE = this.world.getSavedLightValue(LightLayer.Block, blockX - 1,  blockY,     blockZ);
+            final int bS = this.world.getSavedLightValue(LightLayer.Block, blockX,      blockY,     blockZ + 1);
+            final int bN = this.world.getSavedLightValue(LightLayer.Block, blockX,      blockY,     blockZ - 1);
+            if(bW > bU) { bU = bW; }
+            if(bE > bU) { bU = bE; }
+            if(bS > bU) { bU = bS; }
+            if(bN > bU) { bU = bN; }
+            blocklight = bU;
+
+                  int sU = this.world.getSavedLightValue(LightLayer.Sky, blockX,      blockY + 1, blockZ);
+            final int sW = this.world.getSavedLightValue(LightLayer.Sky, blockX + 1,  blockY,     blockZ);
+            final int sE = this.world.getSavedLightValue(LightLayer.Sky, blockX - 1,  blockY,     blockZ);
+            final int sS = this.world.getSavedLightValue(LightLayer.Sky, blockX,      blockY,     blockZ + 1);
+            final int sN = this.world.getSavedLightValue(LightLayer.Sky, blockX,      blockY,     blockZ - 1);
+            if(sW > sU) { sU = sW; }
+            if(sE > sU) { sU = sE; }
+            if(sS > sU) { sU = sS; }
+            if(sN > sU) { sU = sN; }
+            skylight = sU;
+
+        } else {
+            skylight = this.world.getSavedLightValue(LightLayer.Sky, blockX, blockY, blockZ);
+            blocklight = this.world.getSavedLightValue(LightLayer.Block, blockX, blockY, blockZ);
+        }
     	
-    	return world.getLightmapCoord(skylight, blocklight);
+    	return this.world.getLightmapCoord(skylight, blocklight);
     }
 
     public void setWorld(@NotNull final World world)
@@ -952,6 +977,7 @@ public abstract class Entity
     }
 
     public boolean collidesWithBlock(Block<?> block, int metadata) {
+        if (this.pushTime > 0.5f && (this.xd * this.xd + this.yd * this.yd + this.zd * this.zd) > 1 && Block.hasLogicClass(block, BlockLogicPistonHead.class)) return false; // TODO horrible hardcoded exception to getting stuck in piston heads during flings
         return true;
     }
 
diff --git a/game/core/src/main/java/net/minecraft/core/entity/animal/AmbientCreature.java b/game/core/src/main/java/net/minecraft/core/entity/animal/AmbientCreature.java
new file mode 100644
index 000000000..bdb36ebb3
--- /dev/null
+++ b/game/core/src/main/java/net/minecraft/core/entity/animal/AmbientCreature.java
@@ -0,0 +1,4 @@
+package net.minecraft.core.entity.animal;
+
+public interface AmbientCreature extends Creature{
+}
diff --git a/game/core/src/main/java/net/minecraft/core/entity/animal/MobFireflyCluster.java b/game/core/src/main/java/net/minecraft/core/entity/animal/MobFireflyCluster.java
index 6ccccf7c2..bb3d06526 100644
--- a/game/core/src/main/java/net/minecraft/core/entity/animal/MobFireflyCluster.java
+++ b/game/core/src/main/java/net/minecraft/core/entity/animal/MobFireflyCluster.java
@@ -19,7 +19,7 @@ import java.util.List;
 import java.util.Map;
 
 public class MobFireflyCluster extends MobFlying
-        implements Creature
+        implements AmbientCreature
 {
 	public static final int DATA_COLOR_ID = 16;
 	public static final int DATA_CLUSTER_SIZE_ID = 17;
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 f3a8f2d6e..852e112c4 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
@@ -105,7 +105,7 @@ public abstract class Player
     public float sleepOffX;
     public float sleepOffY;
     public float sleepOffZ;
-    private ChunkCoordinates playerSpawnCoordinate;
+    private @Nullable ChunkCoordinates playerSpawnCoordinate;
     private ChunkCoordinates lastDeathCoordinate;
     private ChunkCoordinates startMinecartRidingCoordinate;
     public int timeUntilPortal;
@@ -339,13 +339,26 @@ public abstract class Player
     @Override
 	public void rideTick()
     {
-        double d = x;
-        double d1 = y;
-        double d2 = z;
+        final double xdO = this.xd;
+        final double ydO = this.yd;
+        final double zdO = this.zd;
+        final double xo = this.x;
+        final double yo = this.y;
+        final double zo = this.z;
         super.rideTick();
-        cameraVelocityOld = cameraVelocity;
-        cameraVelocity = 0.0F;
-        addMountedMovementStat(x - d, y - d1, z - d2);
+        this.cameraVelocityOld = this.cameraVelocity;
+        this.cameraVelocity = 0.0F;
+        addMountedMovementStat(this.x - xo, this.y - yo, this.z - zo);
+
+        if (this.vehicle instanceof Entity) {
+            this.xd = ((Entity) this.vehicle).xd;
+            this.yd = ((Entity) this.vehicle).yd;
+            this.zd = ((Entity) this.vehicle).zd;
+        }
+
+        this.xdO = xdO;
+        this.ydO = ydO;
+        this.zdO = zdO;
     }
 
     @Override
@@ -1297,16 +1310,15 @@ public abstract class Player
         return (b = world.getBlock(bedChunkCoordinates.x, bedChunkCoordinates.y, bedChunkCoordinates.z)) != null && b.getLogic() instanceof BlockLogicBed;
     }
 
-    public static ChunkCoordinates getValidBedSpawnCoordinates(World world, ChunkCoordinates coords)
+    public static @Nullable ChunkCoordinates getValidBedSpawnCoordinates(@NotNull final World world, @NotNull final ChunkCoordinates coords)
     {
-        IChunkProvider chunkProvider = world.getChunkProvider();
+        final IChunkProvider chunkProvider = world.getChunkProvider();
         chunkProvider.setCurrentChunkOver(coords.x >> 4, coords.z >> 4);
         chunkProvider.prepareChunk(coords.x - 3 >> 4, coords.z - 3 >> 4);
         chunkProvider.prepareChunk(coords.x + 3 >> 4, coords.z - 3 >> 4);
         chunkProvider.prepareChunk(coords.x - 3 >> 4, coords.z + 3 >> 4);
         chunkProvider.prepareChunk(coords.x + 3 >> 4, coords.z + 3 >> 4);
-        Block<?> b;
-        if ((b = world.getBlock(coords.x, coords.y, coords.z)) != null && b.getLogic() instanceof BlockLogicBed) {
+        if (Block.hasLogicClass(world.getBlock(coords.x, coords.y, coords.z), BlockLogicBed.class)) {
             return BlockLogicBed.getNearestEmptyChunkCoordinates(world, coords.x, coords.y, coords.z, 0);
         } else {
             return null;
@@ -1390,9 +1402,9 @@ public abstract class Player
     {
     }
 
-    public ChunkCoordinates getPlayerSpawnCoordinate()
+    public @Nullable ChunkCoordinates getPlayerSpawnCoordinate()
     {
-        return playerSpawnCoordinate;
+        return this.playerSpawnCoordinate;
     }
 
     public void setPlayerSpawnCoordinate(ChunkCoordinates chunkcoordinates)
diff --git a/game/core/src/main/java/net/minecraft/core/enums/MobCategory.java b/game/core/src/main/java/net/minecraft/core/enums/MobCategory.java
index dcaa347ee..f51929a83 100644
--- a/game/core/src/main/java/net/minecraft/core/enums/MobCategory.java
+++ b/game/core/src/main/java/net/minecraft/core/enums/MobCategory.java
@@ -1,6 +1,7 @@
 package net.minecraft.core.enums;
 
 import net.minecraft.core.entity.Entity;
+import net.minecraft.core.entity.animal.AmbientCreature;
 import net.minecraft.core.entity.animal.MobAnimal;
 import net.minecraft.core.entity.animal.MobWaterAnimal;
 import net.minecraft.core.block.material.Material;
@@ -11,7 +12,7 @@ public enum MobCategory {
 	monster("monster", 0, Enemy.class, 70, Material.air, false),
     creature("creature", 1, MobAnimal.class, 15, Material.air, true),
     waterCreature("waterCreature", 2, MobWaterAnimal.class, 5, Material.water, true),
-    ambientCreature("ambient", 3, Entity.class, 2, Material.air, true);
+    ambientCreature("ambient", 3, AmbientCreature.class, 2, Material.air, true);
 	
 	private final Class<?> baseClass;
 	private final int maxPerChunk;
diff --git a/game/core/src/main/java/net/minecraft/core/net/handler/PacketHandler.java b/game/core/src/main/java/net/minecraft/core/net/handler/PacketHandler.java
index 4ee257f4c..32eba03f5 100644
--- a/game/core/src/main/java/net/minecraft/core/net/handler/PacketHandler.java
+++ b/game/core/src/main/java/net/minecraft/core/net/handler/PacketHandler.java
@@ -78,6 +78,10 @@ public abstract class PacketHandler
         handleInvalidPacket(teleportEntityPacket);
     }
 
+    public void handleEntityFling(PacketEntityFling packetEntityFling) {
+        handleInvalidPacket(packetEntityFling);
+    }
+
     public void handlePlace(PacketUseItem useItemPacket)
     {
         handleInvalidPacket(useItemPacket);
diff --git a/game/core/src/main/java/net/minecraft/core/net/packet/Packet.java b/game/core/src/main/java/net/minecraft/core/net/packet/Packet.java
index f72654a17..c3d8ba23f 100644
--- a/game/core/src/main/java/net/minecraft/core/net/packet/Packet.java
+++ b/game/core/src/main/java/net/minecraft/core/net/packet/Packet.java
@@ -286,6 +286,7 @@ public abstract class Packet
         addMapping(34, true, false, PacketTeleportEntity.class);
         addMapping(35, true, true, PacketEntityNickname.class);
         addMapping(36, true, true, PacketPlayerConfig.class);
+        addMapping(37, true, false, PacketEntityFling.class);
         addMapping(38, true, false, PacketEntityEvent.class);
         addMapping(39, true, false, PacketSetRiding.class);
         addMapping(40, true, false, PacketSetEntityData.class);
diff --git a/game/core/src/main/java/net/minecraft/core/net/packet/PacketAddPlayer.java b/game/core/src/main/java/net/minecraft/core/net/packet/PacketAddPlayer.java
index e1d2d31d4..e13e39b50 100644
--- a/game/core/src/main/java/net/minecraft/core/net/packet/PacketAddPlayer.java
+++ b/game/core/src/main/java/net/minecraft/core/net/packet/PacketAddPlayer.java
@@ -12,86 +12,104 @@ import java.util.UUID;
 
 public class PacketAddPlayer extends Packet
 {
+    public int entityId;
+    public String name;
+    public UUID uuid;
+    public int xPosition;
+    public int yPosition;
+    public int zPosition;
+    public byte rotation;
+    public byte pitch;
+    public int currentItem;
+    public @Nullable CompoundTag heldObjectTag;
+    public String nickname;
+    public byte chatColor;
+    public byte playerConfig;
+    public int gamemode;
 
-    public PacketAddPlayer()
-    {
+
+    public PacketAddPlayer() {
+        super();
     }
 
-    public PacketAddPlayer(Player entityplayer)
-    {
-        entityId = entityplayer.id;
-        name = entityplayer.username;
-        uuid = entityplayer.uuid;
-        xPosition = MathHelper.floor(entityplayer.x * 32D);
-        yPosition = MathHelper.floor(entityplayer.y * 32D);
-        zPosition = MathHelper.floor(entityplayer.z * 32D);
-        rotation = (byte)(int)((entityplayer.yRot * 256F) / 360F);
-        pitch = (byte)(int)((entityplayer.xRot * 256F) / 360F);
-        ItemStack itemstack = entityplayer.inventory.getCurrentItem();
-        currentItem = itemstack != null ? itemstack.itemID : 0;
-        nickname = entityplayer.getDisplayName();
-        chatColor = entityplayer.chatColor;
-        playerConfig = entityplayer.playerConfig.config;
+    public PacketAddPlayer(final Player entityplayer) {
+        super();
+        this.entityId = entityplayer.id;
+        this.name = entityplayer.username;
+        this.uuid = entityplayer.uuid;
+        this.xPosition = MathHelper.floor(entityplayer.x * 32D);
+        this.yPosition = MathHelper.floor(entityplayer.y * 32D);
+        this.zPosition = MathHelper.floor(entityplayer.z * 32D);
+        this.rotation = (byte) (int) ((entityplayer.yRot * 256F) / 360F);
+        this.pitch = (byte) (int) ((entityplayer.xRot * 256F) / 360F);
+        final ItemStack itemstack = entityplayer.inventory.getCurrentItem();
+        this.currentItem = itemstack != null ? itemstack.itemID : 0;
+        this.nickname = entityplayer.getDisplayName();
+        this.chatColor = entityplayer.chatColor;
+        this.playerConfig = entityplayer.playerConfig.config;
         if (entityplayer.getHeldObject() == null) {
-            heldObjectTag = null;
+            this.heldObjectTag = null;
         } else {
-            CompoundTag tag = new CompoundTag();
+            final CompoundTag tag = new CompoundTag();
             entityplayer.getHeldObject().writeToNBT(tag);
-            heldObjectTag = tag;
+            this.heldObjectTag = tag;
         }
+        this.gamemode = entityplayer.gamemode.getId();
     }
 
     @Override
-	public void read(DataInputStream dis)
+	public void read(final DataInputStream dis)
         throws IOException
     {
-        entityId = dis.readInt();
-        name = readString(dis, MAX_USERNAME_SIZE);
-        uuid = readUUID(dis);
-        xPosition = dis.readInt();
-        yPosition = dis.readInt();
-        zPosition = dis.readInt();
-        rotation = dis.readByte();
-        pitch = dis.readByte();
-        currentItem = dis.readShort();
-        nickname = readString(dis, MAX_NICKNAME_SIZE);
-        chatColor = dis.readByte();
-        playerConfig = dis.readByte();
+        this.entityId = dis.readInt();
+        this.name = readString(dis, MAX_USERNAME_SIZE);
+        this.uuid = readUUID(dis);
+        this.xPosition = dis.readInt();
+        this.yPosition = dis.readInt();
+        this.zPosition = dis.readInt();
+        this.rotation = dis.readByte();
+        this.pitch = dis.readByte();
+        this.currentItem = dis.readShort();
+        this.nickname = readString(dis, MAX_NICKNAME_SIZE);
+        this.chatColor = dis.readByte();
+        this.playerConfig = dis.readByte();
+        this.gamemode = Byte.toUnsignedInt(dis.readByte());
 
         if (dis.readByte() == 1) {
-            heldObjectTag = readCompressedCompoundTag(dis);
+            this.heldObjectTag = readCompressedCompoundTag(dis);
         } else {
-            heldObjectTag = null;
+            this.heldObjectTag = null;
         }
     }
 
     @Override
-	public void write(DataOutputStream dos)
+	public void write(final DataOutputStream dos)
         throws IOException
     {
-        dos.writeInt(entityId);
-        writeString(name, dos);
-        writeUUID(uuid, dos);
-        dos.writeInt(xPosition);
-        dos.writeInt(yPosition);
-        dos.writeInt(zPosition);
-        dos.writeByte(rotation);
-        dos.writeByte(pitch);
-        dos.writeShort(currentItem);
-        writeString(nickname, dos);
-        dos.writeByte(chatColor);
-        dos.writeByte(playerConfig);
+        dos.writeInt(this.entityId);
+        writeString(this.name, dos);
+        writeUUID(this.uuid, dos);
+        dos.writeInt(this.xPosition);
+        dos.writeInt(this.yPosition);
+        dos.writeInt(this.zPosition);
+        dos.writeByte(this.rotation);
+        dos.writeByte(this.pitch);
+        dos.writeShort(this.currentItem);
+        writeString(this.nickname, dos);
+        dos.writeByte(this.chatColor);
+        dos.writeByte(this.playerConfig);
+        dos.writeByte(this.gamemode & 0xFF);
 
-        if (heldObjectTag != null) {
+        if (this.heldObjectTag != null) {
             dos.writeByte(1);
-            writeCompressedCompoundTag(heldObjectTag, dos);
+            writeCompressedCompoundTag(this.heldObjectTag, dos);
         } else {
             dos.writeByte(0);
         }
     }
 
     @Override
-	public void handlePacket(PacketHandler packetHandler)
+	public void handlePacket(final PacketHandler packetHandler)
     {
         packetHandler.handleNamedEntitySpawn(this);
     }
@@ -99,20 +117,6 @@ public class PacketAddPlayer extends Packet
     @Override
 	public int getEstimatedSize()
     {
-        return 28;
+        return 29;
     }
-
-    public int entityId;
-    public String name;
-    public UUID uuid;
-    public int xPosition;
-    public int yPosition;
-    public int zPosition;
-    public byte rotation;
-    public byte pitch;
-    public int currentItem;
-    public @Nullable CompoundTag heldObjectTag;
-    public String nickname;
-    public byte chatColor;
-    public byte playerConfig;
 }
diff --git a/game/core/src/main/java/net/minecraft/core/net/packet/PacketEntityFling.java b/game/core/src/main/java/net/minecraft/core/net/packet/PacketEntityFling.java
new file mode 100644
index 000000000..817bf5ab2
--- /dev/null
+++ b/game/core/src/main/java/net/minecraft/core/net/packet/PacketEntityFling.java
@@ -0,0 +1,60 @@
+package net.minecraft.core.net.packet;
+
+import net.minecraft.core.net.handler.PacketHandler;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class PacketEntityFling extends Packet {
+    public int entityId;
+    public double xd;
+    public double yd;
+    public double zd;
+    public float pushTime;
+    public int pushesTick;
+
+    public PacketEntityFling() {
+        super();
+    }
+
+    public PacketEntityFling(final int entityId, final double xd, final double yd, final double zd, final float pushTime, final int pushesTick) {
+        super();
+        this.entityId = entityId;
+        this.xd = xd;
+        this.yd = yd;
+        this.zd = zd;
+        this.pushTime = pushTime;
+        this.pushesTick = pushesTick;
+    }
+
+    @Override
+    public void read(final DataInputStream dis) throws IOException {
+        this.entityId = dis.readInt();
+        this.xd = dis.readFloat();
+        this.yd = dis.readFloat();
+        this.zd = dis.readFloat();
+        this.pushTime = dis.readFloat();
+        this.pushesTick = Byte.toUnsignedInt(dis.readByte());
+    }
+
+    @Override
+    public void write(final DataOutputStream dos) throws IOException {
+        dos.writeInt(this.entityId);
+        dos.writeFloat((float) this.xd);
+        dos.writeFloat((float) this.yd);
+        dos.writeFloat((float) this.zd);
+        dos.writeFloat(this.pushTime);
+        dos.writeByte((byte)this.pushesTick);
+    }
+
+    @Override
+    public void handlePacket(final PacketHandler packetHandler) {
+        packetHandler.handleEntityFling(this);
+    }
+
+    @Override
+    public int getEstimatedSize() {
+        return 21;
+    }
+}
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 6b10221f7..66a4014c8 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
@@ -2887,7 +2887,7 @@ public class World implements WorldSource {
         }
     }
 
-    public boolean canMineBlock(Player entityplayer, int x, int y, int z)
+    public boolean canMineBlock(final Player player, final int x, final int y, final int z)
     {
         return true;
     }
diff --git a/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkCoordinates.java b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkCoordinates.java
index 5677ee88a..785c4a67b 100644
--- a/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkCoordinates.java
+++ b/game/core/src/main/java/net/minecraft/core/world/chunk/ChunkCoordinates.java
@@ -62,4 +62,13 @@ public class ChunkCoordinates implements Comparable<ChunkCoordinates> {
 	public boolean equals(int x, int y, int z) {
 		return this.x == x && this.y == y && this.z == z;
 	}
+
+	@Override
+	public String toString() {
+		return "ChunkCoordinates{" +
+			"x=" + x +
+			", y=" + y +
+			", z=" + z +
+			'}';
+	}
 }
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 8d6aa0a84..12b2b5b15 100644
--- a/game/core/src/main/resources/lang/en_US/gui.lang
+++ b/game/core/src/main/resources/lang/en_US/gui.lang
@@ -401,4 +401,6 @@ model.category.particle.note.slider=Note: %s
 model.category.particle.block.side=Side: %s
 
 gui.credits.button.done=Done
-gui.credits.label.title=Credits
\ No newline at end of file
+gui.credits.label.title=Credits
+
+gui.tooltip.prompt.description=%s: Show more...
\ No newline at end of file
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 4e97a2853..8ba3c223a 100644
--- a/game/core/src/main/resources/lang/en_US/options.lang
+++ b/game/core/src/main/resources/lang/en_US/options.lang
@@ -264,6 +264,7 @@ key.sortInventory=Sort Inventory
 key.openAchievements=Open Achievements Menu
 key.openStatistics=Open Statistics Menu
 key.showConsole=Show Console
+key.description=Show item description
 key.disabled=Disabled
 key.debug.textureAtlas=Show Texture Atlas
 key.debug.reload=Reload textures
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 20759bd6f..ae127c1be 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
@@ -731,6 +731,13 @@ public class PlayerServer extends Player implements ContainerListener {
     	playerNetServerHandler.sendPacket(new PacketSetCarriedItem(i));
     }
 
+    @Override
+    public void fling(final double xd, final double yd, final double zd, final float pushTime) {
+        super.fling(xd, yd, zd, pushTime);
+        this.playerNetServerHandler.sendPacket(new PacketMovePlayer.PosRot(this.x, this.y + 1.625, this.z, this.yRot, this.xRot, false));
+        this.playerNetServerHandler.sendPacket(new PacketEntityFling(this.id, this.xd, this.yd, this.zd, this.pushTime, this.pushesThisTick));
+    }
+
     @Override
     public void setHeldObject(@Nullable ICarriable heldObject) {
         super.setHeldObject(heldObject);
@@ -753,8 +760,8 @@ public class PlayerServer extends Player implements ContainerListener {
 		playerNetServerHandler.sendPacket(new PacketChat(message, 1, AES.keyChain.get(username)));
 	}
 
-    public void teleport(double x, double y, double z, float xr, float yr) {
-        playerNetServerHandler.teleportAndRotate(x, y, z, xr, yr);
+    public void teleport(double x, double y, double z, float yaw, float pitch) {
+        playerNetServerHandler.teleportAndRotate(x, y, z, yaw, pitch);
     }
 
     @Override
diff --git a/game/server/src/main/java/net/minecraft/server/net/PlayerList.java b/game/server/src/main/java/net/minecraft/server/net/PlayerList.java
index d0ce6ff27..9dc1327af 100644
--- a/game/server/src/main/java/net/minecraft/server/net/PlayerList.java
+++ b/game/server/src/main/java/net/minecraft/server/net/PlayerList.java
@@ -201,7 +201,7 @@ public class PlayerList
         return new PlayerServer(server, server.getDimensionWorld(0), username, uuid, new ServerPlayerController(server.getDimensionWorld(0)));
     }
 
-    public PlayerServer recreatePlayerEntity(PlayerServer previousPlayer, int i)
+    public PlayerServer recreatePlayerEntity(PlayerServer previousPlayer, int dimension)
     {
         server.getEntityTracker(previousPlayer.dimension).removeTrackedPlayerSymmetric(previousPlayer);
         server.getEntityTracker(previousPlayer.dimension).untrackEntity(previousPlayer);
@@ -209,7 +209,7 @@ public class PlayerList
         playerEntities.remove(previousPlayer);
         server.getDimensionWorld(previousPlayer.dimension).removePlayer(previousPlayer);
         ChunkCoordinates chunkcoordinates = previousPlayer.getPlayerSpawnCoordinate();
-        previousPlayer.dimension = i;
+        previousPlayer.dimension = dimension;
         PlayerServer newPlayer = new PlayerServer(server, server.getDimensionWorld(previousPlayer.dimension), previousPlayer.username, previousPlayer.uuid, new ServerPlayerController(server.getDimensionWorld(previousPlayer.dimension)));
         newPlayer.id = previousPlayer.id;
         newPlayer.chatColor = previousPlayer.chatColor;
@@ -221,10 +221,12 @@ public class PlayerList
         //entityplayermp1.setGamemodeOnLogin(entityplayermp.gamemode);
         if (chunkcoordinates != null)
         {
-            ChunkCoordinates chunkcoordinates1 = Player.getValidBedSpawnCoordinates(server.getDimensionWorld(previousPlayer.dimension), chunkcoordinates);
-            if (chunkcoordinates1 != null)
+            final ChunkCoordinates bedCoordinates = Player.getValidBedSpawnCoordinates(this.server.getDimensionWorld(previousPlayer.dimension), chunkcoordinates);
+            if (bedCoordinates != null)
             {
-                newPlayer.teleport((float) chunkcoordinates1.x + 0.5F, (float) chunkcoordinates1.y + 0.1F, (float) chunkcoordinates1.z + 0.5F, 0.0F, 0.0F);
+                newPlayer.setPos(bedCoordinates.x + 0.5F, bedCoordinates.y + 0.1F, bedCoordinates.z + 0.5F);
+                newPlayer.xRot = 0;
+                newPlayer.yRot = 0;
                 newPlayer.setPlayerSpawnCoordinate(chunkcoordinates);
             }
             else
@@ -233,8 +235,8 @@ public class PlayerList
             }
         }
         worldserver.chunkProviderServer.prepareChunk((int) newPlayer.x >> 4, (int) newPlayer.z >> 4);
-        for (; worldserver.getCubes(newPlayer, newPlayer.bb).size() != 0; newPlayer.setPos(newPlayer.x, newPlayer.y + 1.0D, newPlayer.z))
-        {
+        while (!worldserver.getCubes(newPlayer, newPlayer.bb).isEmpty()) {
+            newPlayer.setPos(newPlayer.x, newPlayer.y + 1.0D, newPlayer.z);
         }
         newPlayer.playerNetServerHandler.sendPacket(new PacketRespawn((byte) newPlayer.dimension, (byte) Registries.WORLD_TYPES.getNumericIdOfItem(worldserver.worldType)));
         server.playerList.sendPacketToAllPlayers(new PacketPlayerGamemode(newPlayer.id, newPlayer.gamemode.getId()));
diff --git a/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java b/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java
index 56c12ddb3..319a49b98 100644
--- a/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java
+++ b/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java
@@ -128,7 +128,6 @@ public class PacketHandlerServer extends PacketHandler
 
         if (!hasMoved)
         {
-            double d = packet.y - lastPosY;
             double dx = packet.x - lastPosX;
             double dy = packet.y - lastPosY;
             double dz = packet.z - lastPosZ;
@@ -184,6 +183,7 @@ public class PacketHandlerServer extends PacketHandler
             // Update: Removing it breaks boats, so keep it for now
             worldserver.updateEntityWithOptionalForce(((Entity) playerEntity.vehicle), false);
             playerEntity.vehicle.positionRider();
+            mcServer.playerList.onPlayerMoved(playerEntity);
             return;
         }
 
@@ -245,7 +245,7 @@ public class PacketHandlerServer extends PacketHandler
         velSquared = dx * dx + ndy * ndy + dz * dz;
         boolean movedWrong = false;
         // TODO: Check if the player is flying instead of if they can fly, this information should be synced as in BTA flying is more than just no gravity
-        if (!playerEntity.getGamemode().canPlayerFly() && velSquared > 0.0625D && !playerEntity.isPlayerSleeping())
+        if (playerEntity.pushTime < 0.1f && !playerEntity.getGamemode().canPlayerFly() && velSquared > 0.0625D && !playerEntity.isPlayerSleeping())
         {
             movedWrong = true;
             LOGGER.warn("{} moved wrongly!", playerEntity.username);
@@ -254,7 +254,7 @@ public class PacketHandlerServer extends PacketHandler
         }
         playerEntity.absMoveTo(newPosX, newPosY, newPosZ, yRot, xRot);
         boolean insideBlockNew = worldserver.getCubes(playerEntity, playerEntity.bb.copy().getInsetBoundingBox(bb_expand, bb_expand, bb_expand)).isEmpty();
-        if (!playerEntity.getGamemode().canPlayerFly() && insideBlockOld && (movedWrong || !insideBlockNew) && !playerEntity.isPlayerSleeping())
+        if (playerEntity.pushTime < 0.1f && !playerEntity.getGamemode().canPlayerFly() && insideBlockOld && (movedWrong || !insideBlockNew) && !playerEntity.isPlayerSleeping())
         {
             // If the player:
             // - Is inside a block and wasn't on the last tick
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 41383842a..d3acec4d6 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
@@ -53,16 +53,12 @@ public class WorldServer extends World
     }
 
     @Override
-    public boolean canMineBlock(Player entityplayer, int x, int y, int z)
+    public boolean canMineBlock(final Player player, final int x, final int y, final int z)
     {
-        // TODO make spawn protection a named constant *and* server configurable
-        int l = (int)MathHelper.abs(x - levelData.getSpawnX());
-        int i1 = (int)MathHelper.abs(z - levelData.getSpawnZ());
-        if(l > i1)
-        {
-            i1 = l;
-        }
-        return i1 > 16 || mcServer.playerList.isOp(entityplayer.uuid);
+        if (this.mcServer.spawnProtectionRange <= 0 || this.mcServer.playerList.isOp(player.uuid)) return super.canMineBlock(player, x, y, z);
+        final int dx = (int)MathHelper.abs(x - this.levelData.getSpawnX());
+        final int dz = (int)MathHelper.abs(z - this.levelData.getSpawnZ());
+        return Math.max(dx, dz) > this.mcServer.spawnProtectionRange;
     }
 
     @Override
