diff --git a/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java b/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java
index 08aa7c4c9..570704706 100644
--- a/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java
+++ b/game/client/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java
@@ -239,16 +239,6 @@ public class PlayerLocalMultiplayer extends PlayerLocal implements Player.Player
             flashOnSetHealth = true;
         }
     }
-
-    @Override
-	public int getStat(Stat stat)
-    {
-    	if (stat.clientside)
-    	{
-    		return super.getStat(stat);
-    	}
-    	return 0;
-    }
     
     @Override
 	public void syncPlacementMode() {
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 9b086d5b7..af67e6057 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
@@ -39,35 +39,39 @@ public class ScreenChat extends Screen implements ITextField {
 	@Override
 	public void init() {
 		Keyboard.enableRepeatEvents(true);
-		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,
-			(parent, child, minecraft, followParameters) -> 16 + (followParameters ? suggestionsElement.getDefaultParameterPosition() - 1 : 0),
-			(parent, child, minecraft, followParameters) -> minecraft.resolution.getScaledHeightScreenCoords() - 14,
-			ComponentAnchor.BOTTOM_LEFT
-		);
-		if (!this.getText().startsWith("/")) {
-			this.suggestionsElement.hidden = true;
-		} else {
-			this.suggestionsElement.updateSuggestions();
-		}
+		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,
+				(parent, child, minecraft, followParameters) -> 16 + (followParameters ? suggestionsElement.getDefaultParameterPosition() - 1 : 0),
+				(parent, child, minecraft, followParameters) -> minecraft.resolution.getScaledHeightScreenCoords() - 14,
+				ComponentAnchor.BOTTOM_LEFT
+			);
+			if (!this.getText().startsWith("/")) {
+				this.suggestionsElement.hidden = true;
+			} else {
+				this.suggestionsElement.updateSuggestions();
+			}
 
-		if (mc.gameSettings.forceOnscreenKeyboard.value || mc.inputType == InputType.CONTROLLER) {
-			suggestionsElement.hidden = true;
-			mc.displayScreen(new ScreenKeyboard(this, editor,
-				(workingString) -> sendMessage(),
-				(c, k, workingString) -> {
-					suggestionsElement.hidden = !getText().startsWith("/");
-					suggestionsElement.keyTyped(c, k);
-				},
-                s -> {
-					suggestionsElement.hidden = !getText().startsWith("/");
-					suggestionsElement.updateSuggestions();
-				}));
+			if (mc.gameSettings.forceOnscreenKeyboard.value || mc.inputType == InputType.CONTROLLER) {
+				suggestionsElement.hidden = true;
+				mc.displayScreen(new ScreenKeyboard(this, editor,
+					(workingString) -> sendMessage(),
+					(c, k, workingString) -> {
+						suggestionsElement.hidden = !getText().startsWith("/");
+						suggestionsElement.keyTyped(c, k);
+					},
+					s -> {
+						suggestionsElement.hidden = !getText().startsWith("/");
+						suggestionsElement.updateSuggestions();
+					}));
+			}
+		} catch (Exception e) {
+			LOGGER.error("Exception while attempting to initialize chat screen!", e);
 		}
 	}
 
@@ -85,93 +89,105 @@ public class ScreenChat extends Screen implements ITextField {
 		}
 		updateCounter++;
 
-		int dWheel = Mouse.getDWheel();
-		if (dWheel != 0)
-		{
-			if (showEmotePicker) {
-				emotePicker.scrollOffset((int)(-dWheel / 0.1f));
-			} else {
-				mc.hudIngame.chatScroll += dWheel;
+		try {
+			int dWheel = Mouse.getDWheel();
+			if (dWheel != 0)
+			{
+				if (showEmotePicker) {
+					emotePicker.scrollOffset((int)(-dWheel / 0.1f));
+				} else {
+					mc.hudIngame.chatScroll += dWheel;
+				}
 			}
-		}
 
-		if (this.suggestionsElement != null) {
-			this.suggestionsElement.hidden = !this.getText().startsWith("/");
-			this.suggestionsElement.updateScreen(dWheel);
+			if (this.suggestionsElement != null) {
+				this.suggestionsElement.hidden = !this.getText().startsWith("/");
+				this.suggestionsElement.updateScreen(dWheel);
+			}
+		} catch (Exception e) {
+			LOGGER.error("Exception while attempting to tick chat!", e);
 		}
 	}
 
 	@Override
 	public void keyPressed(char eventCharacter, int eventKey, int mx, int my) {
-		boolean handled = false;
+		try {
+			boolean handled = false;
 
-		if (eventKey == Keyboard.KEY_UP) {
-			if (this.suggestionsElement != null) {
-				if (this.suggestionsElement.getCommandIndex() != -1) {
-					this.suggestionsElement.cycleThroughSuggestions(-1);
+			if (eventKey == Keyboard.KEY_UP) {
+				if (this.suggestionsElement != null) {
+					if (this.suggestionsElement.getCommandIndex() != -1) {
+						this.suggestionsElement.cycleThroughSuggestions(-1);
+						handled = true;
+					}
+				}
+				if (!handled && !mc.thePlayer.messageHistory.isEmpty()) {
+					if (currentIndex == 0)
+					{
+						originalMessage = getText();
+					}
+					if (currentIndex < mc.thePlayer.messageHistory.size())
+					{
+						currentIndex++;
+						setText(getMessage(currentIndex));
+						this.editor.setCursor(10000);
+					}
+					editor.setCursor(10000);
+					if (this.suggestionsElement != null) {
+						this.suggestionsElement.updateSuggestions();
+					}
 					handled = true;
 				}
 			}
-			if (!handled && !mc.thePlayer.messageHistory.isEmpty()) {
-				if (currentIndex == 0)
-				{
-					originalMessage = getText();
-				}
-				if (currentIndex < mc.thePlayer.messageHistory.size())
-				{
-					currentIndex++;
-					setText(getMessage(currentIndex));
-					this.editor.setCursor(10000);
-				}
-				editor.setCursor(10000);
+			if (eventKey == Keyboard.KEY_DOWN)
+			{
 				if (this.suggestionsElement != null) {
-					this.suggestionsElement.updateSuggestions();
+					if (this.suggestionsElement.getCommandIndex() != -1) {
+						this.suggestionsElement.cycleThroughSuggestions();
+						handled = true;
+					}
 				}
-				handled = true;
-			}
-		}
-		if (eventKey == Keyboard.KEY_DOWN)
-		{
-			if (this.suggestionsElement != null) {
-				if (this.suggestionsElement.getCommandIndex() != -1) {
-					this.suggestionsElement.cycleThroughSuggestions();
+				if (!handled && currentIndex > 0) {
+					if (currentIndex-1 == 0)
+					{
+						currentIndex--;
+						setText(originalMessage);
+						this.editor.setCursor(10000);
+					}
+					else
+					{
+						currentIndex--;
+						setText(getMessage(currentIndex));
+						this.editor.setCursor(10000);
+					}
+					editor.setCursor(10000);
+					if (this.suggestionsElement != null) {
+						this.suggestionsElement.updateSuggestions();
+					}
 					handled = true;
 				}
 			}
-			if (!handled && currentIndex > 0) {
-				if (currentIndex-1 == 0)
-				{
-					currentIndex--;
-					setText(originalMessage);
-					this.editor.setCursor(10000);
-				}
-				else
-				{
-					currentIndex--;
-					setText(getMessage(currentIndex));
-					this.editor.setCursor(10000);
-				}
-				editor.setCursor(10000);
-				if (this.suggestionsElement != null) {
-					this.suggestionsElement.updateSuggestions();
+			if (eventKey == Keyboard.KEY_ESCAPE && !(this instanceof ScreenSleepMP)) {
+				mc.displayScreen(null);
+				handled = true;
+			}
+			if (eventKey == Keyboard.KEY_RETURN) {
+				String s = message.trim();
+				if (s.length() > 0) {
+					String s1 = message.trim();
+					mc.thePlayer.sendChatMessage(s1);
 				}
+				mc.displayScreen(null);
 				handled = true;
 			}
-		}
-		if (eventKey == Keyboard.KEY_ESCAPE && !(this instanceof ScreenSleepMP)) {
-			mc.displayScreen(null);
-			handled = true;
-		}
-		if (eventKey == Keyboard.KEY_RETURN) {
-			sendMessage();
-			mc.displayScreen(null);
-			handled = true;
-		}
-		if (!handled) {
-			editor.handleInput(eventKey, eventCharacter);
-		}
-		if (this.suggestionsElement != null) {
-			this.suggestionsElement.keyTyped(eventCharacter, eventKey);
+			if (!handled) {
+				editor.handleInput(eventKey, eventCharacter);
+			}
+			if (this.suggestionsElement != null) {
+				this.suggestionsElement.keyTyped(eventCharacter, eventKey);
+			}
+		} catch (Exception e) {
+			LOGGER.error("Exception while attempting to type key!", e);
 		}
 	}
 
@@ -229,25 +245,29 @@ public class ScreenChat extends Screen implements ITextField {
 	@Override
 	public void mouseClicked(int mx, int my, int buttonNum) {
 		super.mouseClicked(mx, my, buttonNum);
-		boolean handled = false;
-		if (buttonNum == 0) {
-			if (mx >= 2 && mx < 14 && my >= height - 14 && my < height - 2) {
-				showEmotePicker = !showEmotePicker;
-				handled = true;
-			}
-			if (!handled && showEmotePicker) {
-				Character c = emotePicker.click(mx - 2, my - (height - 16 - emotePicker.getHeight()));
-				if (c != null) {
-					editor.handleInput(0, c);
-					if (!Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) && !Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) showEmotePicker = false;
+		try {
+			boolean handled = false;
+			if (buttonNum == 0) {
+				if (mx >= 2 && mx < 14 && my >= height - 14 && my < height - 2) {
+					showEmotePicker = !showEmotePicker;
 					handled = true;
 				}
-			}
-			if (!handled) {
-				if (this.suggestionsElement != null) {
-					this.suggestionsElement.mouseClicked(mx, my, buttonNum);
+				if (!handled && showEmotePicker) {
+					Character c = emotePicker.click(mx - 2, my - (height - 16 - emotePicker.getHeight()));
+					if (c != null) {
+						editor.handleInput(0, c);
+						if (!Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) && !Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) showEmotePicker = false;
+						handled = true;
+					}
+				}
+				if (!handled) {
+					if (this.suggestionsElement != null) {
+						this.suggestionsElement.mouseClicked(mx, my, buttonNum);
+					}
 				}
 			}
+		} catch (Exception e) {
+			LOGGER.error("Exception while attempting to click mouse!", e);
 		}
 	}
 
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 319fce2b6..c8c24a439 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
@@ -346,7 +346,7 @@ public class RenderGlobal
         double cameraYaw = camera.getYRot(partialTick);
         double temperature = worldObj.getBlockTemperature((int)cameraX, (int)cameraZ);
         float mult = 0.0f;
-        if (temperature <= 0.4f || worldObj.getSeasonManager().getCurrentSeason() == Seasons.OVERWORLD_WINTER_ENDLESS)
+        if ((temperature <= 0.4f || worldObj.getSeasonManager().getCurrentSeason() == Seasons.OVERWORLD_WINTER_ENDLESS) && worldObj.isChunkLoaded((int)cameraX, (int)cameraZ))
         {
             // temperature from 0.0f to 0.4f
             temperature /= 0.4f;
diff --git a/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelStandard.java b/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelStandard.java
index 6f1dd850a..63385c488 100644
--- a/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelStandard.java
+++ b/game/client/src/main/java/net/minecraft/client/render/item/model/ItemModelStandard.java
@@ -179,11 +179,13 @@ public class ItemModelStandard extends ItemModel{
             tessellator.draw();
         } else {
             tessellator.startDrawingQuads();
+            tessellator.setNormal(0, 1, 0);
             tessellator.addVertexWithUV(-0.5,  0.5, 0, cUMin, cVMin);
             tessellator.addVertexWithUV(-0.5, -0.5, 0, cUMin, cVMax);
             tessellator.addVertexWithUV( 0.5, -0.5, 0, cUMax, cVMax);
             tessellator.addVertexWithUV( 0.5,  0.5, 0, cUMax, cVMin);
 
+            tessellator.setNormal(0, 1, 0);
             tessellator.addVertexWithUV(-0.5,  0.5, 0, cUMin, cVMin);
             tessellator.addVertexWithUV( 0.5,  0.5, 0, cUMax, cVMin);
             tessellator.addVertexWithUV( 0.5, -0.5, 0, cUMax, cVMax);
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 03c24ad2e..cdba02ffa 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
@@ -61,9 +61,6 @@ public class WorldClientMP extends WorldClient {
                 super.markBlockNeedsUpdate(worldblockpositiontype.x, worldblockpositiontype.y, worldblockpositiontype.z);
                 positionTypesList.remove(l--);
             }
-        }
-        if(getGameRuleValue(GameRules.DO_DAY_CYCLE)) {
-            levelData.setWorldTime(levelData.getWorldTime() + 1L);
         }
 		updateSeasonAndLight();
         if(rainbowTicks > 0)
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 7cc5cfa4b..dcf3da443 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
@@ -24,17 +24,7 @@ public class ChunkProviderClient
     @Override
     public boolean isChunkLoaded(int chunkX, int chunkZ)
     {
-        return true;
-
-        // TODO Previous code always returned true, possibly was a bug?
-        /*if(this != null)
-        {
-            return true;
-        } else
-        {
-            ChunkCoordinate chunkcoordintpair = new ChunkCoordinate(chunkX, chunkZ);
-            return chunkMapping.containsKey(chunkcoordintpair);
-        }*/
+        return this.chunkMapping.containsKey(new ChunkCoordinate(chunkX, chunkZ));
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicChest.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicChest.java
index 9c081b1cf..8ad5f97f7 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicChest.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicChest.java
@@ -357,7 +357,7 @@ public class BlockLogicChest extends BlockLogic implements IPaintable {
 				}
 			}
 			if(inv2 != null) {
-				inventory = new ContainerCompound("Large Chest", inventory, inv2);
+				inventory = new ContainerCompound("container.chest.large.name", inventory, inv2);
 			}
 		}
 		
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 852e112c4..f35052c80 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
@@ -250,9 +250,10 @@ public abstract class Player
 	public void tick()
     {
         if (world.dimension == Dimension.NETHER) {
-            if (y >=128) {
+            addStat(Achievements.ENTER_NETHER, 1);
+            /*if (y >=128) {
                 addStat(Achievements.ENTER_NETHER, 1);
-            } /* else {
+            }  else {
                 addStat(Achievements.ENTER_WARRENS, 1);
             }*/
         }
diff --git a/game/core/src/main/java/net/minecraft/core/net/command/util/BeautifulNbt.java b/game/core/src/main/java/net/minecraft/core/net/command/util/BeautifulNbt.java
index cbbe8b1e3..3011c1666 100644
--- a/game/core/src/main/java/net/minecraft/core/net/command/util/BeautifulNbt.java
+++ b/game/core/src/main/java/net/minecraft/core/net/command/util/BeautifulNbt.java
@@ -1,6 +1,7 @@
 package net.minecraft.core.net.command.util;
 
 import com.mojang.nbt.tags.CompoundTag;
+import com.mojang.nbt.tags.ListTag;
 import com.mojang.nbt.tags.Tag;
 import org.jetbrains.annotations.NotNull;
 
@@ -68,7 +69,7 @@ public class BeautifulNbt {
             //noinspection unchecked
             for (Tag<?> element : ((List<Tag<?>>)o)) {
                 if (comma) result.append(", ");
-                result.append(element(element.getValue()));
+                result.append(element(element instanceof CompoundTag ? element : element.getValue()));
                 comma = true;
             }
         }
diff --git a/game/core/src/main/java/net/minecraft/core/net/command/util/CommandHelper.java b/game/core/src/main/java/net/minecraft/core/net/command/util/CommandHelper.java
index 5443f05d9..74575ed23 100644
--- a/game/core/src/main/java/net/minecraft/core/net/command/util/CommandHelper.java
+++ b/game/core/src/main/java/net/minecraft/core/net/command/util/CommandHelper.java
@@ -14,7 +14,10 @@ import net.minecraft.core.net.command.helpers.IntegerCoordinates;
 import net.minecraft.core.util.collection.NamespaceID;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.generate.feature.WorldFeature;
+import net.minecraft.core.world.generate.feature.*;
+import net.minecraft.core.world.generate.feature.tree.*;
+import net.minecraft.core.world.generate.feature.tree.spooner.*;
+import org.jetbrains.annotations.NotNull;
 
 import java.util.HashMap;
 import java.util.Locale;
@@ -146,15 +149,76 @@ public class CommandHelper {
     }
 
     public static void init() {
-        try {
-            for (Class<?> aClass : CommandReflectionHelper.getAllClasses((className) -> className.startsWith("net.minecraft.core.world.generate.feature"))) {
-                if (WorldFeature.class.isAssignableFrom(aClass) && aClass != WorldFeature.class) {
-                    Class<? extends WorldFeature> worldGenClass = (Class<? extends WorldFeature>) aClass;
-                    WORLD_FEATURES.put(aClass.getSimpleName().substring(12), worldGenClass);
-                }
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
+//        try {
+//            for (Class<?> aClass : CommandReflectionHelper.getAllClasses((className) -> className.startsWith("net.minecraft.core.world.generate.feature"))) {
+//                if (WorldFeature.class.isAssignableFrom(aClass) && aClass != WorldFeature.class) {
+//                    Class<? extends WorldFeature> worldGenClass = (Class<? extends WorldFeature>) aClass;
+//                    WORLD_FEATURES.put(aClass.getSimpleName().substring(12), worldGenClass);
+//                }
+//            }
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        }
+        // TODO hopefully find a way to automatically accomplish this without having to manually add all features
+        registerWorldFeatureClass(WorldFeatureAlgae.class);
+        registerWorldFeatureClass(WorldFeatureCactus.class);
+        registerWorldFeatureClass(WorldFeatureClay.class);
+        registerWorldFeatureClass(WorldFeatureDeadBush.class);
+        registerWorldFeatureClass(WorldFeatureDungeon.class);
+        registerWorldFeatureClass(WorldFeatureFire.class);
+        registerWorldFeatureClass(WorldFeatureFlowers.class);
+        registerWorldFeatureClass(WorldFeatureGlowstoneA.class);
+        registerWorldFeatureClass(WorldFeatureGlowstoneB.class);
+        registerWorldFeatureClass(WorldFeatureGrassPatch.class);
+        registerWorldFeatureClass(WorldFeatureLabyrinth.class);
+        registerWorldFeatureClass(WorldFeatureLake.class);
+        registerWorldFeatureClass(WorldFeatureLiquid.class);
+        registerWorldFeatureClass(WorldFeatureMeadow.class);
+        registerWorldFeatureClass(WorldFeatureMudPatch.class);
+        registerWorldFeatureClass(WorldFeatureNetherLava.class);
+        registerWorldFeatureClass(WorldFeatureOre.class);
+        registerWorldFeatureClass(WorldFeaturePermaice.class);
+        registerWorldFeatureClass(WorldFeaturePumice.class);
+        registerWorldFeatureClass(WorldFeaturePumpkin.class);
+        registerWorldFeatureClass(WorldFeatureRichScorchedDirt.class);
+        registerWorldFeatureClass(WorldFeatureSpinifexPatch.class);
+        registerWorldFeatureClass(WorldFeatureSponge.class);
+        registerWorldFeatureClass(WorldFeatureSugarCane.class);
+        registerWorldFeatureClass(WorldFeatureSugarCaneTall.class);
+        registerWorldFeatureClass(WorldFeatureTallGrass.class);
+
+        registerWorldFeatureClass(WorldFeatureCherryTreeFancy.class);
+        registerWorldFeatureClass(WorldFeatureTree.class);
+        registerWorldFeatureClass(WorldFeatureTreeCaatinga.class);
+        registerWorldFeatureClass(WorldFeatureTreeCherry.class);
+        registerWorldFeatureClass(WorldFeatureTreeEucalyptus.class);
+        registerWorldFeatureClass(WorldFeatureTreeFancy.class);
+        registerWorldFeatureClass(WorldFeatureTreeFancyRainforest.class);
+        registerWorldFeatureClass(WorldFeatureTreePalm.class);
+        registerWorldFeatureClass(WorldFeatureTreeShapeSwamp.class);
+        registerWorldFeatureClass(WorldFeatureTreeShrub.class);
+        registerWorldFeatureClass(WorldFeatureTreeTaigaBushy.class);
+        registerWorldFeatureClass(WorldFeatureTreeTaigaTall.class);
+        registerWorldFeatureClass(WorldFeatureTreeTall.class);
+        registerWorldFeatureClass(WorldFeatureTreeThorn.class);
+
+        registerWorldFeatureClass(WorldFeatureSpoonerTree.class);
+        registerWorldFeatureClass(WorldFeatureSpoonerTreeBamboo.class);
+        registerWorldFeatureClass(WorldFeatureSpoonerTreeCone.class);
+        registerWorldFeatureClass(WorldFeatureSpoonerTreeMangrove.class);
+        registerWorldFeatureClass(WorldFeatureSpoonerTreeNormal.class);
+        registerWorldFeatureClass(WorldFeatureSpoonerTreePalm.class);
+        registerWorldFeatureClass(WorldFeatureSpoonerTreeProcedural.class);
+        registerWorldFeatureClass(WorldFeatureSpoonerTreeRainforest.class);
+        registerWorldFeatureClass(WorldFeatureSpoonerTreeRound.class);
+        registerWorldFeatureClass(WorldFeatureSpoonerTreeStick.class);
+    }
+
+    public static <T extends WorldFeature> void registerWorldFeatureClass(@NotNull final Class<T> tClass) {
+        registerWorldFeatureClass(tClass, tClass.getSimpleName().substring(12));
+    }
+
+    public static <T extends WorldFeature> void registerWorldFeatureClass(@NotNull final Class<T> tClass, @NotNull final String name) {
+        WORLD_FEATURES.put(name, tClass);
     }
 }
diff --git a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuAbstract.java b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuAbstract.java
index f13c7e308..995214f2b 100644
--- a/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuAbstract.java
+++ b/game/core/src/main/java/net/minecraft/core/player/inventory/menu/MenuAbstract.java
@@ -423,6 +423,7 @@ public abstract class MenuAbstract
 			return;
 		}
 		slot.sortSlotInventory();
+        this.containerListeners.forEach(c -> c.updateCraftingInventory(this, getSlotStackList()));
 	}
 	
 	/**
diff --git a/game/core/src/main/resources/lang/en_US/strings.lang b/game/core/src/main/resources/lang/en_US/strings.lang
index d283dfed0..10cf51963 100644
--- a/game/core/src/main/resources/lang/en_US/strings.lang
+++ b/game/core/src/main/resources/lang/en_US/strings.lang
@@ -174,6 +174,7 @@ side.none=None
 
 container.activator.name=Activator
 container.chest.name=Chest
+container.chest.large.name=Large Chest
 container.dispenser.name=Dispenser
 container.flag.name=Flag
 container.furnace.name=Furnace
