diff --git a/src/main/java/net/minecraft/client/Minecraft.java b/src/main/java/net/minecraft/client/Minecraft.java
index e6df39416..24b6aacf5 100644
--- a/src/main/java/net/minecraft/client/Minecraft.java
+++ b/src/main/java/net/minecraft/client/Minecraft.java
@@ -1,6 +1,20 @@
 package net.minecraft.client;
 
+import static net.minecraft.core.Global.*;
+import static org.lwjgl.opengl.GL11.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Random;
+
+import org.lwjgl.LWJGLException;
+import org.lwjgl.input.Keyboard;
+import org.lwjgl.input.Mouse;
+import org.lwjgl.opengl.Display;
+
 import com.mojang.nbt.CompoundTag;
+
 import net.minecraft.client.achievement.stat.StatStringFormatKeyInv;
 import net.minecraft.client.discord.RichPresenceHandlerThread;
 import net.minecraft.client.entity.ClientSkinVariantList;
@@ -48,6 +62,7 @@ import net.minecraft.client.player.controller.PlayerController;
 import net.minecraft.client.render.ChunkRenderer;
 import net.minecraft.client.render.EffectRenderer;
 import net.minecraft.client.render.EntityRenderDispatcher;
+import net.minecraft.client.render.FallbackRenderer;
 import net.minecraft.client.render.FontRenderer;
 import net.minecraft.client.render.ItemRenderer;
 import net.minecraft.client.render.LightmapHelper;
@@ -62,9 +77,7 @@ import net.minecraft.client.render.WorldRenderer;
 import net.minecraft.client.render.block.model.BlockModelDispatcher;
 import net.minecraft.client.render.camera.EntityCameraFirstPerson;
 import net.minecraft.client.render.camera.ICamera;
-import net.minecraft.client.render.colorizer.ColorizerFoliage;
-import net.minecraft.client.render.colorizer.ColorizerGrass;
-import net.minecraft.client.render.colorizer.ColorizerWater;
+import net.minecraft.client.render.colorizer.Colorizers;
 import net.minecraft.client.render.item.model.ItemModelDispatcher;
 import net.minecraft.client.render.model.ModelBiped;
 import net.minecraft.client.render.shader.Shaders;
@@ -129,35 +142,6 @@ import net.minecraft.core.world.save.LevelStorage;
 import net.minecraft.core.world.save.SaveConverters;
 import net.minecraft.core.world.save.SaveFormats;
 import net.minecraft.core.world.save.mcregion.SaveFormat19134;
-import org.lwjgl.LWJGLException;
-import org.lwjgl.input.Keyboard;
-import org.lwjgl.input.Mouse;
-import org.lwjgl.opengl.Display;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Random;
-
-import static net.minecraft.core.Global.CURRENT_SAVE_VERSION;
-import static org.lwjgl.opengl.GL11.GL_ALPHA_TEST;
-import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
-import static org.lwjgl.opengl.GL11.glAlphaFunc;
-import static org.lwjgl.opengl.GL11.glBindTexture;
-import static org.lwjgl.opengl.GL11.glClear;
-import static org.lwjgl.opengl.GL11.glClearColor;
-import static org.lwjgl.opengl.GL11.glClearDepth;
-import static org.lwjgl.opengl.GL11.glColor4f;
-import static org.lwjgl.opengl.GL11.glCullFace;
-import static org.lwjgl.opengl.GL11.glDepthFunc;
-import static org.lwjgl.opengl.GL11.glDisable;
-import static org.lwjgl.opengl.GL11.glEnable;
-import static org.lwjgl.opengl.GL11.glLoadIdentity;
-import static org.lwjgl.opengl.GL11.glMatrixMode;
-import static org.lwjgl.opengl.GL11.glOrtho;
-import static org.lwjgl.opengl.GL11.glShadeModel;
-import static org.lwjgl.opengl.GL11.glTranslatef;
-import static org.lwjgl.opengl.GL11.glViewport;
 
 // Referenced classes of package net.minecraft.client:
 //            MinecraftApplet
@@ -226,7 +210,7 @@ public class Minecraft
     public final GameResolution resolution = new GameResolution(this);
     public final ClientCommandHandler commandHandler = new ClientCommandHandler(this);
     public boolean fullbright = false;
-    public Renderer render;
+    public Renderer renderer;
     public ControllerInput controllerInput;
     public final MouseInput mouseInput = new MouseInput(this);
     public InputType inputType = InputType.KEYBOARD;
@@ -381,7 +365,7 @@ public class Minecraft
         if(Shaders.enableShaders) {
             setRenderer(new ShadersRenderer(this));
         }else {
-            setRenderer(new Renderer(this));
+            setRenderer(new FallbackRenderer(this));
         }
 
         texturePackList = new TexturePackList(this, mcDataDir);
@@ -394,15 +378,7 @@ public class Minecraft
         
         // Initialize overworld biome map
         BiomeProviderOverworld.init();
-
-        ColorizerWater.updateColorData(renderEngine.getTextureImageData("/misc/watercolor.png"));
-        ColorizerGrass.defaultColor.updateColorData(renderEngine.getTextureImageData("/misc/grasscolor.png"));
-        ColorizerGrass.spring.updateColorData(renderEngine.getTextureImageData("/misc/grasscolor_spring.png"));
-        ColorizerGrass.summer.updateColorData(renderEngine.getTextureImageData("/misc/grasscolor.png"));
-        ColorizerGrass.fall.updateColorData(renderEngine.getTextureImageData("/misc/grasscolor_fall.png"));
-        ColorizerGrass.winter.updateColorData(renderEngine.getTextureImageData("/misc/grasscolor_winter.png"));
-        ColorizerFoliage.updateColorData(renderEngine.getTextureImageData("/misc/foliagecolor.png"));
-
+        
         worldRenderer = new WorldRenderer(this);
 
         // I hate initialization issues so much
@@ -453,6 +429,8 @@ public class Minecraft
         
         loadScreen();	// Update loading screen so it doesn't say no response
         
+        Colorizers.init(this);
+        
         renderEngine.refreshTextures(new ArrayList<>());
 
         loadScreen();	// Update loading screen so it doesn't say no response
@@ -891,7 +869,7 @@ public class Minecraft
                     Debug.change("render"); // 2
                     Debug.push("post"); // 3
                     
-                    render.beginRenderGame(timer.partialTicks);
+                    renderer.beginRenderGame(timer.partialTicks);
                     glEnable(GL_ALPHA_TEST);
 
                     Debug.change("misc");  // 3
@@ -917,7 +895,7 @@ public class Minecraft
                     guiAchievement.updateAchievementWindow();
 
                     Debug.change("post");  // 3
-                    render.endRenderGame(timer.partialTicks);
+                    renderer.endRenderGame(timer.partialTicks);
                     
                     Debug.pop();	// 3
                     
@@ -1220,9 +1198,6 @@ public class Minecraft
                 chunkproviderloadorgenerate.setCurrentChunkOver(playerChunkX, playerChunkZ);
             }
         }
-        if(theWorld != null) {
-        	theWorld.updateAllOnLightChange = !LightmapHelper.isLightmapEnabled();
-        }
         if(!isGamePaused && theWorld != null)
         {
             playerController.tick();
@@ -1492,7 +1467,7 @@ public class Minecraft
                             displayInGameMenu();
                         }
                         else if (Keyboard.getEventKey() == Keyboard.KEY_F7) {
-                            render.reload();
+                            renderer.reload();
                         }
                         else if (gameSettings.keyCommand.isPressed())
                         {
@@ -1913,7 +1888,7 @@ public class Minecraft
         sndManager.loadSoundSettings(gameSettings);
         downloadResourcesThread.reloadResources();
         renderEngine.refreshTexturesAndDisplayErrors();
-        render.reload();
+        renderer.reload();
         if (renderGlobal != null){
             renderGlobal.loadRenderers();
         }
@@ -2101,6 +2076,7 @@ public class Minecraft
             loadingScreen.progressStop();
         }
         worldRenderer.lightmapHelper.setup();
+        Colorizers.update(true);
     }
 
     private void convertSaveVersion(int fromVersion, String worldDirName, String worldName)
@@ -2324,11 +2300,11 @@ public class Minecraft
     }
     
     public void setRenderer(Renderer renderer) {
-        if(this.render != null) {
-            this.render.delete();
+        if(this.renderer != null) {
+            this.renderer.delete();
         }
-        this.render = renderer;
-        this.render.reload();
+        this.renderer = renderer;
+        this.renderer.reload();
     }
 
     public static void startMainThread(String username, String sessionId)
diff --git a/src/main/java/net/minecraft/client/discord/RichPresenceHandlerThread.java b/src/main/java/net/minecraft/client/discord/RichPresenceHandlerThread.java
index fb3fe72ac..16e748cea 100644
--- a/src/main/java/net/minecraft/client/discord/RichPresenceHandlerThread.java
+++ b/src/main/java/net/minecraft/client/discord/RichPresenceHandlerThread.java
@@ -39,7 +39,6 @@ public class RichPresenceHandlerThread extends Thread
         biomeNamesMap.put(Biomes.OVERWORLD_SWAMPLAND, "the swamplands");
         biomeNamesMap.put(Biomes.OVERWORLD_SEASONAL_FOREST, "a seasonal forest");
         biomeNamesMap.put(Biomes.OVERWORLD_FOREST, "a forest");
-        biomeNamesMap.put(Biomes.OVERWORLD_FOREST_DRY, "a dry forest");
         biomeNamesMap.put(Biomes.OVERWORLD_GRASSLANDS, "the grasslands");
         biomeNamesMap.put(Biomes.OVERWORLD_OUTBACK, "the outback");
         biomeNamesMap.put(Biomes.OVERWORLD_SHRUBLAND, "a shrubland");
diff --git a/src/main/java/net/minecraft/client/gui/GuiIngame.java b/src/main/java/net/minecraft/client/gui/GuiIngame.java
index 97d4ea9c2..ab4d71d30 100644
--- a/src/main/java/net/minecraft/client/gui/GuiIngame.java
+++ b/src/main/java/net/minecraft/client/gui/GuiIngame.java
@@ -1,5 +1,17 @@
 package net.minecraft.client.gui;
 
+import static net.minecraft.core.util.helper.Utils.*;
+import static org.lwjgl.opengl.GL11.*;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.lwjgl.input.Keyboard;
+import org.lwjgl.opengl.GL11;
+
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.entity.player.EntityClientPlayerMP;
 import net.minecraft.client.gui.hud.HudComponent;
@@ -20,7 +32,6 @@ import net.minecraft.core.data.tag.Tag;
 import net.minecraft.core.entity.player.EntityPlayer;
 import net.minecraft.core.enums.LightLayer;
 import net.minecraft.core.item.Item;
-import net.minecraft.core.item.ItemFood;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.lang.I18n;
 import net.minecraft.core.net.ChatLine;
@@ -32,29 +43,6 @@ import net.minecraft.core.world.season.Season;
 import net.minecraft.core.world.weather.Weather;
 import net.minecraft.core.world.wind.WindManager;
 
-import org.lwjgl.input.Keyboard;
-import org.lwjgl.opengl.GL11;
-
-import java.awt.*;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static net.minecraft.core.util.helper.Utils.floor10;
-import static net.minecraft.core.util.helper.Utils.floor100;
-import static net.minecraft.core.util.helper.Utils.percentRound;
-import static org.lwjgl.opengl.GL11.GL_ALPHA_TEST;
-import static org.lwjgl.opengl.GL11.GL_BLEND;
-import static org.lwjgl.opengl.GL11.GL_LIGHTING;
-import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
-import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA;
-import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
-import static org.lwjgl.opengl.GL11.glBlendFunc;
-import static org.lwjgl.opengl.GL11.glColor4d;
-import static org.lwjgl.opengl.GL11.glDisable;
-import static org.lwjgl.opengl.GL11.glEnable;
-
 public class GuiIngame extends Gui
 {
 
@@ -214,7 +202,7 @@ public class GuiIngame extends Gui
                 drawDebugScreenLineRight(GL11.glGetString(GL11.GL_RENDERER));
                 drawDebugScreenLineRight(GL11.glGetString(GL11.GL_VERSION));
                 drawDebugScreenLineRight("Resolution: " + mc.resolution.width + "x" + mc.resolution.height);
-                drawDebugScreenLineRight("Render Resolution: " + mc.render.renderWidth + "x" + mc.render.renderHeight);
+                drawDebugScreenLineRight("Render Resolution: " + mc.renderer.getRenderWidth() + "x" + mc.renderer.getRenderHeight());
                 drawDebugScreenLine("Better than Adventure! " + Minecraft.VERSION);
                 drawDebugScreenLine(mc.debug);
                 drawDebugScreenLine(mc.getRendererDebugInfo());
diff --git a/src/main/java/net/minecraft/client/gui/GuiPhotoMode.java b/src/main/java/net/minecraft/client/gui/GuiPhotoMode.java
index aa7c17200..b79326202 100644
--- a/src/main/java/net/minecraft/client/gui/GuiPhotoMode.java
+++ b/src/main/java/net/minecraft/client/gui/GuiPhotoMode.java
@@ -83,8 +83,8 @@ public class GuiPhotoMode extends GuiScreen
             photoModeRenderer = new PhotoModeRenderer(mc, this);
         }
         
-        this.previousRenderer = mc.render;
-        mc.renderGlobal.allChanged();
+        this.previousRenderer = mc.renderer;
+        mc.theWorld.updateSeasonAndLight();
         originalTOD = mc.theWorld.getWorldTime();
     }
 
@@ -198,7 +198,7 @@ public class GuiPhotoMode extends GuiScreen
             mc.setRenderer(previousRenderer);
         }
 
-        mc.renderGlobal.allChanged();
+        mc.theWorld.updateSeasonAndLight();
     }
 
     @Override
@@ -229,7 +229,7 @@ public class GuiPhotoMode extends GuiScreen
             }
 
             mc.theWorld.setWorldTimeUpdateTicks(desiredDay + desiredTOD);
-            mc.theWorld.doSeasonUpdate(true);
+            mc.theWorld.updateSeasonAndLight();
         }
         else if (button == buttonTakeScreenshot)
         {
@@ -396,7 +396,7 @@ public class GuiPhotoMode extends GuiScreen
             }
 
             mc.theWorld.setWorldTimeUpdateTicks(desiredDay + desiredTOD);
-            mc.theWorld.doLightingUpdate();
+            mc.theWorld.updateSeasonAndLight();
 
             updateButtonsText();
         }
diff --git a/src/main/java/net/minecraft/client/gui/modelviewer/GuiModelViewer.java b/src/main/java/net/minecraft/client/gui/modelviewer/GuiModelViewer.java
index b36113763..aa2cec406 100644
--- a/src/main/java/net/minecraft/client/gui/modelviewer/GuiModelViewer.java
+++ b/src/main/java/net/minecraft/client/gui/modelviewer/GuiModelViewer.java
@@ -88,7 +88,7 @@ public class GuiModelViewer extends GuiPhotoMode implements GuiListenerTextField
             photoModeRenderer = new PhotoModeRenderer(mc, this);
         }
 
-        this.previousRenderer = mc.render;
+        this.previousRenderer = mc.renderer;
         showPlayer = false;
         showHelpText = false;
         lastIZoom = iZoom = iZoomGoal = 8.5f;
@@ -449,7 +449,7 @@ public class GuiModelViewer extends GuiPhotoMode implements GuiListenerTextField
         try {
             File screenshotsDir = new File(mc.getMinecraftDir(), "screenshots");
             screenshotsDir.mkdir();
-            Texture texture = ((ShadersRenderer)mc.render).getWorldFramebufferTex();
+            Texture texture = ((ShadersRenderer)mc.renderer).getWorldFramebufferTex();
             texture.bind();
 
             int w = glGetTexLevelParameteri(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH);
diff --git a/src/main/java/net/minecraft/client/render/FallbackRenderer.java b/src/main/java/net/minecraft/client/render/FallbackRenderer.java
new file mode 100644
index 000000000..0c1a3789e
--- /dev/null
+++ b/src/main/java/net/minecraft/client/render/FallbackRenderer.java
@@ -0,0 +1,58 @@
+package net.minecraft.client.render;
+
+import net.minecraft.client.Minecraft;
+
+public class FallbackRenderer implements Renderer {
+
+	public Minecraft mc;
+	
+	public FallbackRenderer(Minecraft minecraft) {
+		mc = minecraft;
+	}
+	
+	@Override
+	public void beginRenderGame(float partialTicks) {
+		
+	}
+
+	@Override
+	public void endRenderGame(float partialTicks) {
+		
+	}
+
+	@Override
+	public void beginRenderWorld(float partialTicks) {
+		
+	}
+
+	@Override
+	public void endRenderWorld(float partialTicks) {
+		
+	}
+
+	@Override
+	public void reload() {
+		
+	}
+
+	@Override
+	public void delete() {
+		
+	}
+
+	@Override
+	public void create() {
+		
+	}
+
+	@Override
+	public int getRenderWidth() {
+		return mc.resolution.width;
+	}
+
+	@Override
+	public int getRenderHeight() {
+		return mc.resolution.height;
+	}
+
+}
diff --git a/src/main/java/net/minecraft/client/render/FogManager.java b/src/main/java/net/minecraft/client/render/FogManager.java
index 20408bc83..3e46d7808 100644
--- a/src/main/java/net/minecraft/client/render/FogManager.java
+++ b/src/main/java/net/minecraft/client/render/FogManager.java
@@ -12,9 +12,8 @@ import net.minecraft.client.gui.GuiPhotoMode;
 import net.minecraft.client.gui.modelviewer.GuiModelViewer;
 import net.minecraft.client.option.enums.RenderDistance;
 import net.minecraft.client.render.camera.CameraUtil;
-import net.minecraft.client.render.colorizer.ColorizerWater;
+import net.minecraft.client.render.colorizer.Colorizers;
 import net.minecraft.core.block.material.Material;
-import net.minecraft.core.net.packet.Packet;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.util.phys.Vec3d;
 import net.minecraft.core.world.Dimension;
@@ -117,7 +116,7 @@ public class FogManager {
         float gSky = (float)skyColor.yCoord;
         float bSky = (float)skyColor.zCoord;
 
-        Vec3d worldColor = world.getFogColor(mc.thePlayer.x, mc.thePlayer.y, mc.thePlayer.z, partialTick);
+        Vec3d worldColor = world.getFogColor(mc.activeCamera, partialTick);
         fogRed = (float)worldColor.xCoord;
         fogGreen = (float)worldColor.yCoord;
         fogBlue = (float)worldColor.zCoord;
@@ -144,8 +143,8 @@ public class FogManager {
                 int z = MathHelper.floor_double(mc.activeCamera.getZ(partialTick));
                 double temp = world.getBlockTemperature(x, z);
                 double humid = world.getBlockHumidity(x, z);
-                int waterColor = ColorizerWater.getWaterColor(temp, humid);
-
+                int waterColor = Colorizers.water.getColor(temp, humid);
+                
                 float red = ((waterColor >> 16) & 0xFF) / 255F;
                 float green = ((waterColor >> 8) & 0xFF) / 255F;
                 float blue = (waterColor & 0xFF) / 255F;
diff --git a/src/main/java/net/minecraft/client/render/Framebuffer.java b/src/main/java/net/minecraft/client/render/Framebuffer.java
index 342c80e56..597e1ea88 100644
--- a/src/main/java/net/minecraft/client/render/Framebuffer.java
+++ b/src/main/java/net/minecraft/client/render/Framebuffer.java
@@ -2,39 +2,45 @@ package net.minecraft.client.render;
 
 import static org.lwjgl.opengl.ARBFramebufferObject.*;
 
-public class Framebuffer extends GLObject<Framebuffer>{
+public class Framebuffer {
 	
 	private int id;
 	
-	public Framebuffer generate() {
+	public boolean generate() {
 		if(isGenerated()) {
-			delete();
+			return false;
 		}
+		
 		this.id = glGenFramebuffers();
-		if(this.id == 0) throw new RuntimeException("Framebuffer not created!");
-		return this;
+		if(!isGenerated()) {
+			throw new RuntimeException("Framebuffer not created!");
+		}
+		
+		return true;
 	}
 	
-	public void delete() {
-		if(!isGenerated()) return;
+	public boolean delete() {
+		if(!isGenerated()) {
+			return false;
+		}
+		
 		glDeleteFramebuffers(id);
 		id = 0;
+		return true;
 	}
 	
-	@Override
-	public Framebuffer bind() {
-		if(!isGenerated()) throw new NullPointerException();
+	public boolean bind() {
+		if(!isGenerated()) {
+			return false;
+		}
 		glBindFramebuffer(GL_FRAMEBUFFER, id);
-		return this;
+		return true;
 	}
 	
-	@Override
-	public Framebuffer unbind() {
+	public void unbind() {
 		glBindFramebuffer(GL_FRAMEBUFFER, 0);
-		return this;
 	}
 	
-	@Override
 	public boolean isGenerated() {
 		return id != 0;
 	}
diff --git a/src/main/java/net/minecraft/client/render/GLObject.java b/src/main/java/net/minecraft/client/render/GLObject.java
deleted file mode 100644
index ef17f828d..000000000
--- a/src/main/java/net/minecraft/client/render/GLObject.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package net.minecraft.client.render;
-
-public abstract class GLObject<O extends GLObject<O>> {
-	
-	public abstract O bind();
-	
-	public abstract O unbind();
-	
-	public abstract boolean isGenerated();
-
-}
diff --git a/src/main/java/net/minecraft/client/render/LoadingScreenRenderer.java b/src/main/java/net/minecraft/client/render/LoadingScreenRenderer.java
index e3ef32389..f9a5adeb0 100644
--- a/src/main/java/net/minecraft/client/render/LoadingScreenRenderer.java
+++ b/src/main/java/net/minecraft/client/render/LoadingScreenRenderer.java
@@ -158,7 +158,7 @@ public class LoadingScreenRenderer
         }
         startTime = time;
 
-        minecraft.render.beginRenderGame(1.0f);
+        minecraft.renderer.beginRenderGame(1.0f);
     	glEnable(GL_ALPHA_TEST);
 
         // Set up background
@@ -215,7 +215,7 @@ public class LoadingScreenRenderer
         // Draw tip
         minecraft.fontRenderer.drawStringWithShadow(tip, (width - minecraft.fontRenderer.getStringWidth(tip)) / 2, (height / 2 - 4) + 32, 0xffffff);
         
-        minecraft.render.endRenderGame(1.0f);
+        minecraft.renderer.endRenderGame(1.0f);
         
         Display.update();
         try
diff --git a/src/main/java/net/minecraft/client/render/RenderEngine.java b/src/main/java/net/minecraft/client/render/RenderEngine.java
index 30d703bd6..b0eb10ab2 100644
--- a/src/main/java/net/minecraft/client/render/RenderEngine.java
+++ b/src/main/java/net/minecraft/client/render/RenderEngine.java
@@ -1,18 +1,29 @@
 package net.minecraft.client.render;
 
+import static net.minecraft.client.util.helper.Textures.*;
+import static net.minecraft.core.util.helper.Buffer.*;
+import static org.lwjgl.opengl.GL11.*;
+import static org.lwjgl.opengl.GL12.*;
+
+import java.awt.image.BufferedImage;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 import com.b100.json.element.JsonArray;
 import com.b100.json.element.JsonElement;
 import com.b100.json.element.JsonObject;
+
 import net.minecraft.client.GLAllocation;
 import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.popup.GuiPopup;
 import net.minecraft.client.gui.popup.PopupBuilder;
 import net.minecraft.client.option.GameSettings;
 import net.minecraft.client.option.enums.MipmapType;
-import net.minecraft.client.render.colorizer.ColorProperties;
-import net.minecraft.client.render.colorizer.ColorizerFoliage;
-import net.minecraft.client.render.colorizer.ColorizerGrass;
-import net.minecraft.client.render.colorizer.ColorizerWater;
+import net.minecraft.client.render.colorizer.Colorizers;
 import net.minecraft.client.render.dynamictexture.DynamicTexture;
 import net.minecraft.client.render.dynamictexture.DynamicTextureCalendar;
 import net.minecraft.client.render.dynamictexture.DynamicTextureClock;
@@ -36,43 +47,6 @@ import net.minecraft.client.util.helper.Colors;
 import net.minecraft.client.util.helper.TexturePackJsonHelper;
 import net.minecraft.client.util.helper.Textures;
 import net.minecraft.core.util.helper.Buffer;
-import net.minecraft.core.util.helper.Color;
-import net.minecraft.core.world.season.Seasons;
-
-import java.awt.image.BufferedImage;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-import static net.minecraft.client.util.helper.Textures.getImageData;
-import static net.minecraft.client.util.helper.Textures.missingTexture;
-import static net.minecraft.client.util.helper.Textures.readImage;
-import static net.minecraft.client.util.helper.Textures.unwrapImageByColumns;
-import static net.minecraft.core.util.helper.Buffer.buffer;
-import static org.lwjgl.opengl.GL11.GL_CLAMP;
-import static org.lwjgl.opengl.GL11.GL_LINEAR;
-import static org.lwjgl.opengl.GL11.GL_NEAREST;
-import static org.lwjgl.opengl.GL11.GL_NEAREST_MIPMAP_LINEAR;
-import static org.lwjgl.opengl.GL11.GL_REPEAT;
-import static org.lwjgl.opengl.GL11.GL_RGBA;
-import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
-import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
-import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER;
-import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_S;
-import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_T;
-import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE;
-import static org.lwjgl.opengl.GL11.glBindTexture;
-import static org.lwjgl.opengl.GL11.glDeleteTextures;
-import static org.lwjgl.opengl.GL11.glGetTexParameteri;
-import static org.lwjgl.opengl.GL11.glTexImage2D;
-import static org.lwjgl.opengl.GL11.glTexParameteri;
-import static org.lwjgl.opengl.GL11.glTexSubImage2D;
-import static org.lwjgl.opengl.GL12.GL_TEXTURE_MAX_LEVEL;
 
 public class RenderEngine {
 
@@ -739,34 +713,12 @@ public class RenderEngine {
 		Colors.loadColors();
 		
 		mc.fontRenderer = new FontRenderer(gameSettings, "/font/default.png", this);
-
-		// Reload colors
-		Properties colors = new Properties();
-		InputStream stream = null;
-		try {
-			stream = texturePacks.getResourceAsStream("/misc/colors.properties");
-			colors.load(stream);
-		}catch (IOException ignored) {
-			
-		}finally {
-			try {
-				// CLOSE YOUR INPUT STREAMS
-				stream.close();
-			}catch (Exception e) {}
-		}
-		ColorProperties.loadColors(colors);
 		
 		mc.skinVariantList.refresh(errors);
 		mc.mainMenuBackground.refresh(errors);
 		
-        ColorizerWater.updateColorData(mc.renderEngine.getTextureImageData("/misc/watercolor.png"));
-		ColorizerGrass.defaultColor.updateColorData(mc.renderEngine.getTextureImageData("/misc/grasscolor.png"));
-		ColorizerGrass.spring.updateColorData(mc.renderEngine.getTextureImageData("/misc/grasscolor_spring.png"));
-		ColorizerGrass.summer.updateColorData(mc.renderEngine.getTextureImageData("/misc/grasscolor.png"));
-		ColorizerGrass.fall.updateColorData(mc.renderEngine.getTextureImageData("/misc/grasscolor_fall.png"));
-		ColorizerGrass.winter.updateColorData(mc.renderEngine.getTextureImageData("/misc/grasscolor_winter.png"));
-        ColorizerFoliage.updateColorData(mc.renderEngine.getTextureImageData("/misc/foliagecolor.png"));
-        ColorizerGrass.update(true);
+        Colorizers.reload();
+        
         mc.worldRenderer.lightmapHelper.setup();
 	}
 
diff --git a/src/main/java/net/minecraft/client/render/RenderGlobal.java b/src/main/java/net/minecraft/client/render/RenderGlobal.java
index e28a7e0fa..a3cdcfc8b 100644
--- a/src/main/java/net/minecraft/client/render/RenderGlobal.java
+++ b/src/main/java/net/minecraft/client/render/RenderGlobal.java
@@ -12,6 +12,7 @@ import net.minecraft.client.render.block.model.BlockModelDispatcher;
 import net.minecraft.client.render.block.model.BlockModelLeaves;
 import net.minecraft.client.render.camera.EntityCamera;
 import net.minecraft.client.render.camera.ICamera;
+import net.minecraft.client.render.colorizer.Colorizers;
 import net.minecraft.client.render.culling.CameraFrustum;
 import net.minecraft.client.render.stitcher.IconCoordinate;
 import net.minecraft.client.render.stitcher.TextureRegistry;
@@ -293,7 +294,7 @@ public class RenderGlobal
 
     public void renderAurora(ICamera camera, float partialTick)
     {
-        float celestialAngle = worldObj.getWorldType().getCelestialAngle(worldObj, worldObj.getWorldTime(), partialTick);
+        float celestialAngle = worldObj.getCelestialAngle(partialTick);
         if (celestialAngle < 0.25f) return;
 
         double cameraX = camera.getX(partialTick);
@@ -957,7 +958,7 @@ public class RenderGlobal
         GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, renderEngine.getTexture("/environment/clouds.png"));
         GL11.glEnable(3042 /*GL_BLEND*/);
         GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
-        Vec3d dimensionColor = worldObj.getDimensionColor(partialTick);
+        Vec3d dimensionColor = worldObj.getDimensionColor(mc.activeCamera, partialTick);
         float r = (float)dimensionColor.xCoord;
         float g = (float)dimensionColor.yCoord;
         float b = (float)dimensionColor.zCoord;
@@ -1004,7 +1005,7 @@ public class RenderGlobal
             aSun = sunriseColor[3] / 2;
         }
 
-        Vec3d dimensionColor = worldObj.getDimensionColor(partialTick);
+        Vec3d dimensionColor = worldObj.getDimensionColor(mc.activeCamera, partialTick);
         float rDim = (float)dimensionColor.xCoord;
         float gDim = (float)dimensionColor.yCoord;
         float bDim = (float)dimensionColor.zCoord;
@@ -1631,19 +1632,20 @@ public class RenderGlobal
         }
     }
     
-    @Override
-    public void allChanged()
-    {
-        for (ChunkRenderer chunkRenderer : chunkRenderers)
-        {
-            if (chunkRenderer.isChunkLit && !chunkRenderer.needsUpdate)
-            {
-                chunkRenderersToUpdate.add(chunkRenderer);
-                chunkRenderer.markDirty();
-            }
-        }
-
-    }
+	@Override
+	public void allChanged(boolean lightChanged, boolean seasonChanged) {
+		if(seasonChanged) {
+			Colorizers.update(false);
+		}
+		if(seasonChanged || lightChanged && !LightmapHelper.isLightmapEnabled()) {
+			for(ChunkRenderer chunkRenderer : chunkRenderers) {
+				if(chunkRenderer.isChunkLit && !chunkRenderer.needsUpdate) {
+					chunkRenderersToUpdate.add(chunkRenderer);
+					chunkRenderer.markDirty();
+				}
+			}
+		}
+	}
 
     @Override
     public void tileEntityChanged(int x, int y, int z, TileEntity tileEntity)
diff --git a/src/main/java/net/minecraft/client/render/Renderer.java b/src/main/java/net/minecraft/client/render/Renderer.java
index 555722055..02e90068a 100644
--- a/src/main/java/net/minecraft/client/render/Renderer.java
+++ b/src/main/java/net/minecraft/client/render/Renderer.java
@@ -1,45 +1,23 @@
 package net.minecraft.client.render;
 
-import net.minecraft.client.Minecraft;
-
-public class Renderer {
-	
-	public final Minecraft mc;
+public interface Renderer {
 	
-	public int renderWidth;
-	public int renderHeight;
+	public void beginRenderGame(float partialTicks);
 	
-	public Renderer(Minecraft minecraft) {
-		this.mc = minecraft;
-	}
+	public void endRenderGame(float partialTicks);
 	
-	public void beginRenderGame(float partialTicks) {
-		renderWidth = mc.resolution.width;
-		renderHeight = mc.resolution.height;
-	}
+	public void beginRenderWorld(float partialTicks);
 	
-	public void endRenderGame(float partialTicks) {
-		
-	}
+	public void endRenderWorld(float partialTicks);
 	
-	public void beginRenderWorld(float partialTicks) {
-		
-	}
+	public void reload();
 	
-	public void endRenderWorld(float partialTicks) {
-		
-	}
+	public void delete();
 	
-	public void reload() {
-		
-	}
+	public void create();
 	
-	public void delete() {
-		
-	}
+	public int getRenderWidth();
 	
-	public void create() {
-		
-	}
+	public int getRenderHeight();
 	
 }
diff --git a/src/main/java/net/minecraft/client/render/Texture.java b/src/main/java/net/minecraft/client/render/Texture.java
index dc6afba98..a51d63c8f 100644
--- a/src/main/java/net/minecraft/client/render/Texture.java
+++ b/src/main/java/net/minecraft/client/render/Texture.java
@@ -4,37 +4,45 @@ import static org.lwjgl.opengl.GL11.*;
 
 import net.minecraft.client.GLAllocation;
 
-public class Texture extends GLObject<Texture>{
+public class Texture {
 	
 	private int id;
 	
-	public Texture generate() {
-		if(isGenerated()) delete();
+	public boolean generate() {
+		if(isGenerated()) {
+			return false;
+		}
+		
 		id = GLAllocation.generateTexture();
-		if(!isGenerated()) throw new RuntimeException("Texture not created!");
-		return this;
+		if(!isGenerated()) {
+			throw new RuntimeException("Texture not created!");
+		}
+		
+		return true;
 	}
 	
-	@Override
-	public Texture bind() {
-		if(!isGenerated()) throw new NullPointerException();
+	public boolean delete() {
+		if(!isGenerated()) {
+			return false;
+		}
+		GLAllocation.deleteTexture(id);
+		id = 0;
+		return true;
+	}
+	
+	public boolean bind() {
+		if(!isGenerated()) {
+			return false;
+		}
+		
 		glBindTexture(GL_TEXTURE_2D, id);
-		return this;
+		return true;
 	}
 
-	@Override
-	public Texture unbind() {
+	public void unbind() {
 		glBindTexture(GL_TEXTURE_2D, 0);
-		return this;
-	}
-	
-	public void delete() {
-		if(!isGenerated()) return;
-		GLAllocation.deleteTexture(id);
-		id = 0;
 	}
 	
-	@Override
 	public boolean isGenerated() {
 		return id != 0;
 	}
diff --git a/src/main/java/net/minecraft/client/render/WorldRenderer.java b/src/main/java/net/minecraft/client/render/WorldRenderer.java
index 76eecae66..02eadbb28 100644
--- a/src/main/java/net/minecraft/client/render/WorldRenderer.java
+++ b/src/main/java/net/minecraft/client/render/WorldRenderer.java
@@ -1,11 +1,11 @@
 package net.minecraft.client.render;
 
+import static org.lwjgl.opengl.GL11.*;
+
 import java.util.List;
 import java.util.Random;
 
-import net.minecraft.client.render.colorizer.ColorizerGrass;
 import org.lwjgl.input.Mouse;
-import org.lwjgl.opengl.GL11;
 import org.lwjgl.util.glu.GLU;
 
 import net.minecraft.client.Minecraft;
@@ -24,6 +24,7 @@ import net.minecraft.client.render.camera.EntityCameraIsometric;
 import net.minecraft.client.render.camera.EntityCameraSleeping;
 import net.minecraft.client.render.camera.EntityCameraThirdPersonFront;
 import net.minecraft.client.render.camera.EntityCameraThirdPersonRear;
+import net.minecraft.client.render.colorizer.Colorizers;
 import net.minecraft.client.render.culling.Frustum;
 import net.minecraft.client.render.stitcher.TextureRegistry;
 import net.minecraft.client.render.tessellator.Tessellator;
@@ -50,6 +51,21 @@ public class WorldRenderer
 {
     public static final long nsPerSecond = 1_000_000_000L;
     public final LightmapHelper lightmapHelper;
+    public Minecraft mc;
+    private float farPlaneDistance;
+    public ItemRenderer itemRenderer;
+    public FogManager fogManager;
+    private int rendererUpdateCount;
+    private Entity pointedEntity;
+    private MouseFilter mouseFilterXAxis;
+    private MouseFilter mouseFilterYAxis;
+    private float fovModifier;
+    private float fovModifierLast;
+    private long systemTime;
+    private Random random;
+    private int rainSoundCounter;
+    public boolean zooming = false;
+    private float zoomProgress;
 
     public WorldRenderer(Minecraft minecraft)
     {
@@ -59,29 +75,11 @@ public class WorldRenderer
         pointedEntity = null;
         mouseFilterXAxis = new MouseFilter();
         mouseFilterYAxis = new MouseFilter();
-        mouseFilterDummy1 = new MouseFilter();
-        mouseFilterDummy2 = new MouseFilter();
-        mouseFilterDummy3 = new MouseFilter();
-        mouseFilterDummy4 = new MouseFilter();
-        cameraDistance = 4F;
-        cameraDistanceO = 4F;
-        field_22226_t = 0.0F;
-        field_22225_u = 0.0F;
-        field_22224_v = 0.0F;
-        field_22223_w = 0.0F;
-        field_22222_x = 0.0F;
-        field_22221_y = 0.0F;
-        field_22220_z = 0.0F;
-        field_22230_A = 0.0F;
-        cameraZoom = 1.0D;
-        cameraYaw = 0.0D;
-        cameraPitch = 0.0D;
-        prevFrameTime = System.currentTimeMillis();
+        fovModifier = 0.0F;
+        fovModifierLast = 0.0F;
         systemTime = 0L;
         random = new Random();
         rainSoundCounter = 0;
-        field_1394_b = 0;
-        field_1393_c = 0;
         itemRenderer = new ItemRenderer(minecraft);
         fogManager = new FogManager(mc);
     }
@@ -89,11 +87,7 @@ public class WorldRenderer
     public void updateRenderer()
     {
         updateSpeedFov();
-        cameraDistanceO = cameraDistance;
-        field_22225_u = field_22226_t;
-        field_22223_w = field_22224_v;
-        field_22221_y = field_22222_x;
-        field_22230_A = field_22220_z;
+        fovModifierLast = fovModifier;
         if(mc.activeCamera == null)
         {
             mc.activeCamera = new EntityCameraFirstPerson(mc, mc.thePlayer);
@@ -216,7 +210,7 @@ public class WorldRenderer
             float f2 = (float)entityliving.deathTime + partialTick;
             f1 /= (1.0F - 500F / (f2 + 500F)) * 2.0F + 1.0F;
         }
-        return f1 + field_22221_y + (field_22222_x - field_22221_y) * partialTick;
+        return f1 + fovModifierLast + (fovModifier - fovModifierLast) * partialTick;
     }
 
     private void hurtCameraEffect(float partialTick)
@@ -227,7 +221,7 @@ public class WorldRenderer
         if(entityliving.getHealth() <= 0)
         {
             float f2 = (float)entityliving.deathTime + partialTick;
-            GL11.glRotatef(40F - 8000F / (f2 + 200F), 0.0F, 0.0F, 1.0F);
+            glRotatef(40F - 8000F / (f2 + 200F), 0.0F, 0.0F, 1.0F);
         }
         if(f1 < 0.0F)
         {
@@ -237,9 +231,9 @@ public class WorldRenderer
             f1 /= entityliving.maxHurtTime;
             f1 = MathHelper.sin(f1 * f1 * f1 * f1 * 3.141593F);
             float f3 = entityliving.attackedAtYaw;
-            GL11.glRotatef(-f3, 0.0F, 1.0F, 0.0F);
-            GL11.glRotatef(-f1 * 14F, 0.0F, 0.0F, 1.0F);
-            GL11.glRotatef(f3, 0.0F, 1.0F, 0.0F);
+            glRotatef(-f3, 0.0F, 1.0F, 0.0F);
+            glRotatef(-f1 * 14F, 0.0F, 0.0F, 1.0F);
+            glRotatef(f3, 0.0F, 1.0F, 0.0F);
             return;
         }
     }
@@ -252,15 +246,13 @@ public class WorldRenderer
             float f1 = entityplayer.walkDist - entityplayer.walkDistO;
             float f2 = -(entityplayer.walkDist + f1 * partialTick);
             float f3 = entityplayer.field_775_e + (entityplayer.field_774_f - entityplayer.field_775_e) * partialTick;
-            float f4 = entityplayer.prevCameraPitch + (entityplayer.cameraPitch - entityplayer.prevCameraPitch) * partialTick;
             if (entityplayer.isSkating)
             {
                 f2 *= 0.25f;
-                f4 *= 0.25f;
             };
-            GL11.glTranslatef(MathHelper.sin(f2 * 3.141593F) * f3 * 0.5F, -java.lang.Math.abs(MathHelper.cos(f2 * 3.141593F) * f3), 0.0F);
-            GL11.glRotatef(MathHelper.sin(f2 * 3.141593F) * f3 * 3F, 0.0F, 0.0F, 1.0F);
-            GL11.glRotatef(java.lang.Math.abs(MathHelper.cos(f2 * 3.141593F - 0.2F) * f3) * 5F, 1.0F, 0.0F, 0.0F);
+            glTranslatef(MathHelper.sin(f2 * 3.141593F) * f3 * 0.5F, -java.lang.Math.abs(MathHelper.cos(f2 * 3.141593F) * f3), 0.0F);
+            glRotatef(MathHelper.sin(f2 * 3.141593F) * f3 * 3F, 0.0F, 0.0F, 1.0F);
+            glRotatef(java.lang.Math.abs(MathHelper.cos(f2 * 3.141593F - 0.2F) * f3) * 5F, 1.0F, 0.0F, 0.0F);
         }
     }
 
@@ -306,23 +298,22 @@ public class WorldRenderer
 
         if(!(mc.currentScreen instanceof GuiPhotoMode) && !mc.gameSettings.lockCamera.value)
         {
-            GL11.glRotatef((float) mc.activeCamera.getXRot(partialTick), 1.0F, 0.0F, 0.0F);
-            GL11.glRotatef((float) (mc.activeCamera.getYRot(partialTick) + 180F), 0.0F, 1.0F, 0.0F);
+            glRotatef((float) mc.activeCamera.getXRot(partialTick), 1.0F, 0.0F, 0.0F);
+            glRotatef((float) (mc.activeCamera.getYRot(partialTick) + 180F), 0.0F, 1.0F, 0.0F);
         }
 
         if (mc.currentScreen instanceof GuiPhotoMode)
         {
-            GL11.glRotatef(((GuiPhotoMode)mc.currentScreen).getTilt(partialTick), 1.0F, 0.0F, 0.0F);
-            GL11.glRotatef(45f + 45F * ((GuiPhotoMode)mc.currentScreen).getRotation(partialTick), 0.0F, 1.0F, 0.0F);
+            glRotatef(((GuiPhotoMode)mc.currentScreen).getTilt(partialTick), 1.0F, 0.0F, 0.0F);
+            glRotatef(45f + 45F * ((GuiPhotoMode)mc.currentScreen).getRotation(partialTick), 0.0F, 1.0F, 0.0F);
         }
     }
 
     private void setupCameraTransform(float partialTick)
     {
         farPlaneDistance = mc.gameSettings.renderDistance.value.chunks * 16;
-        GL11.glMatrixMode(5889 /*GL_PROJECTION*/);
-        GL11.glLoadIdentity();
-        float f1 = 0.07F;
+        glMatrixMode(GL_PROJECTION);
+        glLoadIdentity();
         float fov = getFOVModifier(partialTick, true);
         if(zooming) {
             fov = getZoomedFOV(fov, partialTick);
@@ -332,21 +323,15 @@ public class WorldRenderer
         if (mc.currentScreen instanceof GuiPhotoMode)
         {
             double div = java.lang.Math.pow(2, ((GuiPhotoMode)mc.currentScreen).getZoom(partialTick));
-            GL11.glTranslatef(1, 1, 0);
-            GL11.glOrtho(0, mc.resolution.width / div, 0, mc.resolution.height / div, farPlaneDistance * -2.0f, farPlaneDistance * 2.0f);
-            GL11.glTranslatef(((GuiPhotoMode)mc.currentScreen).getPanX(partialTick), -((GuiPhotoMode)mc.currentScreen).getPanY(partialTick), 0);
-        }
-        else if(cameraZoom != 1.0D)
-        {
-            GL11.glTranslatef((float)cameraYaw, (float)(-cameraPitch), 0.0F);
-            GL11.glScaled(cameraZoom, cameraZoom, 1.0D);
-            GLU.gluPerspective(fov, (float)mc.resolution.width / (float)mc.resolution.height, 0.05F, farPlaneDistance * 2.0F);
+            glTranslatef(1, 1, 0);
+            glOrtho(0, mc.resolution.width / div, 0, mc.resolution.height / div, farPlaneDistance * -2.0f, farPlaneDistance * 2.0f);
+            glTranslatef(((GuiPhotoMode)mc.currentScreen).getPanX(partialTick), -((GuiPhotoMode)mc.currentScreen).getPanY(partialTick), 0);
         } else
         {
             GLU.gluPerspective(fov, (float)mc.resolution.width / (float)mc.resolution.height, 0.05F, farPlaneDistance * 2.0F);
         }
-        GL11.glMatrixMode(GL11.GL_MODELVIEW);
-        GL11.glLoadIdentity();
+        glMatrixMode(GL_MODELVIEW);
+        glLoadIdentity();
         hurtCameraEffect(partialTick);
         if(mc.gameSettings.viewBobbing.value && !(mc.currentScreen instanceof GuiPhotoMode))
         {
@@ -357,17 +342,17 @@ public class WorldRenderer
         {
             float f3 = 5F / (f2 * f2 + 5F) - f2 * 0.04F;
             f3 *= f3;
-            GL11.glRotatef(((float)rendererUpdateCount + partialTick) * 20F, 0.0F, 1.0F, 1.0F);
-            GL11.glScalef(1.0F / f3, 1.0F, 1.0F);
-            GL11.glRotatef(-((float)rendererUpdateCount + partialTick) * 20F, 0.0F, 1.0F, 1.0F);
+            glRotatef(((float)rendererUpdateCount + partialTick) * 20F, 0.0F, 1.0F, 1.0F);
+            glScalef(1.0F / f3, 1.0F, 1.0F);
+            glRotatef(-((float)rendererUpdateCount + partialTick) * 20F, 0.0F, 1.0F, 1.0F);
         }
         orientCamera(partialTick);
     }
 
-    private void setupPlayerCamera(float partialTick)
+    private void renderHand(float partialTick)
     {
-        GL11.glMatrixMode(5889 /*GL_PROJECTION*/);
-        GL11.glLoadIdentity();
+        glMatrixMode(GL_PROJECTION);
+        glLoadIdentity();
         float fov = getFOVModifier(partialTick, false);
         if(zooming){
             fov = getZoomedFOV(fov, partialTick);
@@ -375,19 +360,14 @@ public class WorldRenderer
             zoomProgress = 0;
         }
         // Fix hand being rendered inside of blocks / behind rain
-        GL11.glTranslatef(0.0f, 0.0f, -1.0f);
-        GL11.glScalef(1.0f, 1.0f, 0.1f);
+        glTranslatef(0.0f, 0.0f, -1.0f);
+        glScalef(1.0f, 1.0f, 0.1f);
         
-        if(cameraZoom != 1.0D)
-        {
-            GL11.glTranslatef((float)cameraYaw, (float)(-cameraPitch), 0.0F);
-            GL11.glScaled(cameraZoom, cameraZoom, 1.0D);
-        }
         GLU.gluPerspective(fov, (float)mc.resolution.width / (float)mc.resolution.height, 0.05F, farPlaneDistance * 2.0F);
-        GL11.glMatrixMode(5888 /*GL_MODELVIEW0_ARB*/);
-        GL11.glLoadIdentity();
+        glMatrixMode(GL_MODELVIEW);
+        glLoadIdentity();
 
-        GL11.glPushMatrix();
+        glPushMatrix();
         hurtCameraEffect(partialTick);
         if(mc.gameSettings.viewBobbing.value)
         {
@@ -399,7 +379,11 @@ public class WorldRenderer
             if(!zooming) itemRenderer.renderItemInFirstPerson(partialTick);
             lightmapHelper.disableLightmapRendering();
         }
-        GL11.glPopMatrix();
+        glPopMatrix();
+        
+        Debug.change("post");
+        mc.renderer.endRenderWorld(partialTick);
+        
         if(mc.gameSettings.thirdPersonView.value == 0 && !(!(mc.activeCamera instanceof EntityCamera) || ((EntityCamera) mc.activeCamera).entity.isPlayerSleeping()))
         {
             itemRenderer.renderOverlays(partialTick);
@@ -513,12 +497,9 @@ public class WorldRenderer
         } else {
             c = mc.gameSettings.customFpsLimit.value;
         }
-        GL11.glViewport(0, 0, mc.resolution.width, mc.resolution.height);
+        glViewport(0, 0, mc.resolution.width, mc.resolution.height);
         if(mc.theWorld != null)
         {
-            Debug.change("post");
-            mc.render.beginRenderWorld(partialTick);
-            
             Debug.change("world");
             if(!mc.gameSettings.enableVsync.value && mc.gameSettings.customFpsLimit.value == 0) // Max FPS
             {
@@ -547,18 +528,16 @@ public class WorldRenderer
                 Debug.change("misc");
             }
             systemTime = System.nanoTime();
-
-            Debug.change("post");
-            mc.render.endRenderWorld(partialTick);
+            
             Debug.change("hud");
             mc.ingameGUI.renderGameOverlay(partialTick, mc.currentScreen != null, mouseX, mouseY);
             Debug.change("misc");
         } else
         {
-            GL11.glMatrixMode(5889 /*GL_PROJECTION*/);
-            GL11.glLoadIdentity();
-            GL11.glMatrixMode(5888 /*GL_MODELVIEW0_ARB*/);
-            GL11.glLoadIdentity();
+            glMatrixMode(GL_PROJECTION);
+            glLoadIdentity();
+            glMatrixMode(GL_MODELVIEW);
+            glLoadIdentity();
             setupScaledResolution();
             if(mc.gameSettings.enableVsync.value || mc.gameSettings.customFpsLimit.value > 0)
             {
@@ -586,7 +565,7 @@ public class WorldRenderer
         if(mc.currentScreen != null)
         {
             Debug.change("gui");
-            GL11.glClear(256);
+            glClear(256);
             if(mc.inputType == InputType.CONTROLLER) {
                 mouseX = (int) mc.controllerInput.cursorX;
                 mouseY = (int) mc.controllerInput.cursorY;
@@ -602,12 +581,13 @@ public class WorldRenderer
     public void renderWorld(float partialTick, long updateRenderersUntil)
     {
     	Debug.push("misc");
+        Colorizers.update(false);
+        
         RenderGlobal renderGlobal = mc.renderGlobal;
         EffectRenderer effectRenderer = mc.effectRenderer;
-        ColorizerGrass.update(false);
-
-        GL11.glEnable(GL11.GL_CULL_FACE);
-        GL11.glEnable(GL11.GL_DEPTH_TEST);
+        
+        glEnable(GL_CULL_FACE);
+        glEnable(GL_DEPTH_TEST);
         if(mc.activeCamera == null)
         {
             mc.activeCamera = new EntityCameraFirstPerson(mc, mc.thePlayer);
@@ -634,25 +614,28 @@ public class WorldRenderer
         }
 
         fogManager.updateFogColor(partialTick);
-        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
-        GL11.glEnable(2884 /*GL_CULL_FACE*/);
+        
+        Debug.change("post");
+        mc.renderer.beginRenderWorld(partialTick);
+        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+        glEnable(GL_CULL_FACE);
         setupCameraTransform(partialTick);
         Frustum.getFrustum();
         Debug.change("sky");
         if(mc.gameSettings.renderDistance.value.renderSky && !(mc.currentScreen instanceof GuiModelViewer))
         {
             fogManager.setupFog(FogManager.FOG_MODE_SKY, farPlaneDistance, partialTick);
-            GL11.glDisable(GL11.GL_FOG);
+            glDisable(GL_FOG);
 
             renderGlobal.drawSky(partialTick);
         }
         
         Debug.change("misc");
-        GL11.glEnable(2912 /*GL_FOG*/);
+        glEnable(GL_FOG);
         fogManager.setupFog(FogManager.FOG_MODE_NORMAL, farPlaneDistance, partialTick);
         if(mc.gameSettings.ambientOcclusion.value)
         {
-            GL11.glShadeModel(7425 /*GL_SMOOTH*/);
+            glShadeModel(7425 /*GL_SMOOTH*/);
         }
         
         mc.renderGlobal.clipRenderersByFrustum(mc.activeCamera.getFrustum(), partialTick);
@@ -675,7 +658,7 @@ public class WorldRenderer
         } while(l1 >= 0L && l1 <= nsPerSecond);
 
         fogManager.setupFog(FogManager.FOG_MODE_NORMAL, farPlaneDistance, partialTick);
-        GL11.glEnable(2912 /*GL_FOG*/);
+        glEnable(GL_FOG);
         TextureRegistry.blockAtlas.bindTexture();
         Lighting.disable();
 
@@ -684,16 +667,16 @@ public class WorldRenderer
         renderGlobal.sortAndRender(mc.activeCamera, 0, partialTick);
 
         Debug.change("entities");
-        GL11.glShadeModel(7424 /*GL_FLAT*/);
+        glShadeModel(GL_FLAT);
         Lighting.enableLight();
         if (!mc.gameSettings.fog.value)
         {
-            GL11.glDisable(GL11.GL_FOG);
+            glDisable(GL_FOG);
         }
         renderGlobal.renderEntities(mc.activeCamera, partialTick);
         if (!mc.gameSettings.fog.value)
         {
-            GL11.glEnable(GL11.GL_FOG);
+            glEnable(GL_FOG);
         }
         
         Debug.change("particles");
@@ -707,10 +690,10 @@ public class WorldRenderer
         Debug.change("outline");
         if(mc.objectMouseOver != null)
         {
-            GL11.glDisable(GL11.GL_ALPHA_TEST);
+            glDisable(GL_ALPHA_TEST);
             renderGlobal.drawBlockBreaking(mc.activeCamera, mc.objectMouseOver, partialTick);
             renderGlobal.drawSelectionBox(mc.activeCamera, mc.objectMouseOver, partialTick);
-            GL11.glEnable(GL11.GL_ALPHA_TEST);
+            glEnable(GL_ALPHA_TEST);
         }
         
         Debug.change("debugoverlays");
@@ -722,10 +705,10 @@ public class WorldRenderer
         {
         	renderGlobal.drawDebugChunkBorders(mc.activeCamera, partialTick);
         }
-        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
         fogManager.setupFog(FogManager.FOG_MODE_NORMAL, farPlaneDistance, partialTick);
-        GL11.glEnable(GL11.GL_BLEND);
-        GL11.glDisable(GL11.GL_CULL_FACE);
+        glEnable(GL_BLEND);
+        glDisable(GL_CULL_FACE);
         TextureRegistry.blockAtlas.bindTexture();
 
         Debug.change("water");
@@ -733,26 +716,26 @@ public class WorldRenderer
         {
             if(mc.gameSettings.ambientOcclusion.value)
             {
-                GL11.glShadeModel(GL11.GL_SMOOTH);
+                glShadeModel(GL_SMOOTH);
             }
-            GL11.glColorMask(false, false, false, false);
+            glColorMask(false, false, false, false);
             int i1 = renderGlobal.sortAndRender(mc.activeCamera, 1, partialTick);
-            GL11.glColorMask(true, true, true, true);
+            glColorMask(true, true, true, true);
             if(i1 > 0)
             {
                 lightmapHelper.enableLightmapRendering();
                 if (!mc.gameSettings.fog.value)
                 {
-                    GL11.glDisable(GL11.GL_FOG);
+                    glDisable(GL_FOG);
                 }
                 renderGlobal.callAllDisplayLists(1, partialTick);
                 if (!mc.gameSettings.fog.value)
                 {
-                    GL11.glEnable(GL11.GL_FOG);
+                    glEnable(GL_FOG);
                 }
                 lightmapHelper.disableLightmapRendering();
             }
-            GL11.glShadeModel(GL11.GL_FLAT);
+            glShadeModel(GL_FLAT);
         }
         else
         {
@@ -762,27 +745,24 @@ public class WorldRenderer
         }
         
         Debug.change("weather");
-        GL11.glDepthMask(true);
-        GL11.glEnable(GL11.GL_CULL_FACE);
-        GL11.glDisable(GL11.GL_BLEND);
+        glDepthMask(true);
+        glEnable(GL_CULL_FACE);
+        glDisable(GL_BLEND);
         renderRainSnow(partialTick);
-        GL11.glDisable(GL11.GL_FOG);
+        glDisable(GL_FOG);
         if(mc.gameSettings.clouds.value) {
         	Debug.change("clouds");
             fogManager.setupFog(FogManager.FOG_MODE_NORMAL, farPlaneDistance, partialTick);
-            GL11.glEnable(GL11.GL_FOG);
+            glEnable(GL_FOG);
             renderGlobal.renderClouds(partialTick);
-            GL11.glDisable(GL11.GL_FOG);
+            glDisable(GL_FOG);
         }
 
         Debug.change("misc");
         fogManager.setupFog(1, farPlaneDistance, partialTick);
-        if(cameraZoom == 1.0D)
-        {
-            setupPlayerCamera(partialTick);
-        }
-
-        GL11.glColorMask(true, true, true, true);
+        renderHand(partialTick);
+        
+        glColorMask(true, true, true, true);
         Debug.pop();
     }
 
@@ -872,13 +852,13 @@ public class WorldRenderer
         int posY = MathHelper.floor_double(mc.activeCamera.getY());
         int posZ = MathHelper.floor_double(mc.activeCamera.getZ());
         Tessellator tessellator = Tessellator.instance;
-        GL11.glDisable(2884 /*GL_CULL_FACE*/);
-        GL11.glNormal3f(0.0F, 1.0F, 0.0F);
-        GL11.glEnable(3042 /*GL_BLEND*/);
-        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
-        GL11.glAlphaFunc(516, 0.01F);
+        glDisable(2884 /*GL_CULL_FACE*/);
+        glNormal3f(0.0F, 1.0F, 0.0F);
+        glEnable(3042 /*GL_BLEND*/);
+        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+        glAlphaFunc(516, 0.01F);
         
-        GL11.glBindTexture(3553 /*GL_TEXTURE_2D*/, mc.renderEngine.getTexture(weather.texturePath));
+        glBindTexture(3553 /*GL_TEXTURE_2D*/, mc.renderEngine.getTexture(weather.texturePath));
         
         double nextPosX = mc.activeCamera.getX(partialTick);
         double nextPosY = mc.activeCamera.getY(partialTick);
@@ -926,7 +906,7 @@ public class WorldRenderer
                         tessellator.startDrawingQuads();
                         float f12 = world.getLightBrightness(x, i3, z);
                         if (mc.fullbright) f12 = 1.0f;
-                        GL11.glColor4f(f12, f12, f12, ((1.0F - f11 * f11) * 0.3F + 0.5F) * world.weatherManager.getWeatherIntensity() * world.weatherManager.getWeatherPower());
+                        glColor4f(f12, f12, f12, ((1.0F - f11 * f11) * 0.3F + 0.5F) * world.weatherManager.getWeatherIntensity() * world.weatherManager.getWeatherPower());
                         tessellator.setTranslation(-nextPosX * 1.0D, -nextPosY * 1.0D, -nextPosZ * 1.0D);
                         tessellator.addVertexWithUV(x + 0, k3, (double)z + 0.5D, 0.0F * f3 + f7, ((float)k3 * f3) / 4F + f6 * f3 + f8);
                         tessellator.addVertexWithUV(x + 1, k3, (double)z + 0.5D, 1.0F * f3 + f7, ((float)k3 * f3) / 4F + f6 * f3 + f8);
@@ -973,7 +953,7 @@ public class WorldRenderer
                         tessellator.startDrawingQuads();
                         float f10 = world.getLightBrightness(x, world.getHeightBlocks(), z) * 0.85F + 0.15F;
                         if (mc.fullbright) f10 = 1.0f;
-                        GL11.glColor4f(f10, f10, f10, ((1.0F - f9 * f9) * 0.5F + 0.5F) * (world.weatherManager.getWeatherIntensity() - 0.1f) * world.weatherManager.getWeatherPower());
+                        glColor4f(f10, f10, f10, ((1.0F - f9 * f9) * 0.5F + 0.5F) * (world.weatherManager.getWeatherIntensity() - 0.1f) * world.weatherManager.getWeatherPower());
                         tessellator.setTranslation(-nextPosX * 1.0D, -nextPosY * 1.0D, -nextPosZ * 1.0D);
                         tessellator.addVertexWithUV(x + 0, j3, (double)z + 0.5D, 0.0F * f2, ((float)j3 * f2) / 4F + f4 * f2);
                         tessellator.addVertexWithUV(x + 1, j3, (double)z + 0.5D, 1.0F * f2, ((float)j3 * f2) / 4F + f4 * f2);
@@ -1027,7 +1007,7 @@ public class WorldRenderer
                         tessellator.startDrawingQuads();
                         float f10 = world.getLightBrightness(x, world.getHeightBlocks(), z) * 0.85F + 0.15F;
                         if (mc.fullbright) f10 = 1.0f;
-                        GL11.glColor4f(f10, f10, f10, ((1.0F - f9 * f9) * 0.5F + 0.5F) * (world.weatherManager.getWeatherIntensity() - 0.1f) * world.weatherManager.getWeatherPower());
+                        glColor4f(f10, f10, f10, ((1.0F - f9 * f9) * 0.5F + 0.5F) * (world.weatherManager.getWeatherIntensity() - 0.1f) * world.weatherManager.getWeatherPower());
                         tessellator.setTranslation(-nextPosX * 1.0D, -nextPosY * 1.0D, -nextPosZ * 1.0D);
                         tessellator.addVertexWithUV(x + 0, j3, (double)z + 0.5D, 0.0F * f2, ((float)j3 * f2) / 4F - vOffset * f2);
                         tessellator.addVertexWithUV(x + 1, j3, (double)z + 0.5D, 1.0F * f2, ((float)j3 * f2) / 4F - vOffset * f2);
@@ -1046,53 +1026,19 @@ public class WorldRenderer
         }
 
 
-        GL11.glEnable(2884 /*GL_CULL_FACE*/);
-        GL11.glDisable(3042 /*GL_BLEND*/);
-        GL11.glAlphaFunc(516, 0.1F);
+        glEnable(2884 /*GL_CULL_FACE*/);
+        glDisable(3042 /*GL_BLEND*/);
+        glAlphaFunc(516, 0.1F);
     }
 
     public void setupScaledResolution()
     {
-        GL11.glClear(256);
-        GL11.glMatrixMode(5889 /*GL_PROJECTION*/);
-        GL11.glLoadIdentity();
-        GL11.glOrtho(0.0D, mc.resolution.scaledWidthExact, mc.resolution.scaledHeightExact, 0.0D, 1000D, 3000D);
-        GL11.glMatrixMode(5888 /*GL_MODELVIEW0_ARB*/);
-        GL11.glLoadIdentity();
-        GL11.glTranslatef(0.0F, 0.0F, -2000F);
+        glClear(256);
+        glMatrixMode(5889 /*GL_PROJECTION*/);
+        glLoadIdentity();
+        glOrtho(0.0D, mc.resolution.scaledWidthExact, mc.resolution.scaledHeightExact, 0.0D, 1000D, 3000D);
+        glMatrixMode(5888 /*GL_MODELVIEW0_ARB*/);
+        glLoadIdentity();
+        glTranslatef(0.0F, 0.0F, -2000F);
     }
-
-    public Minecraft mc;
-    private float farPlaneDistance;
-    public ItemRenderer itemRenderer;
-    public FogManager fogManager;
-    private int rendererUpdateCount;
-    private Entity pointedEntity;
-    private MouseFilter mouseFilterXAxis;
-    private MouseFilter mouseFilterYAxis;
-    private MouseFilter mouseFilterDummy1;
-    private MouseFilter mouseFilterDummy2;
-    private MouseFilter mouseFilterDummy3;
-    private MouseFilter mouseFilterDummy4;
-    private float cameraDistance;
-    private float cameraDistanceO;
-    private float field_22226_t;
-    private float field_22225_u;
-    private float field_22224_v;
-    private float field_22223_w;
-    private float field_22222_x;
-    private float field_22221_y;
-    private float field_22220_z;
-    private float field_22230_A;
-    private double cameraZoom;
-    private double cameraYaw;
-    private double cameraPitch;
-    private long prevFrameTime;
-    private long systemTime;
-    private Random random;
-    private int rainSoundCounter;
-    volatile int field_1394_b;
-    volatile int field_1393_c;
-    public boolean zooming = false;
-    private float zoomProgress;
 }
diff --git a/src/main/java/net/minecraft/client/render/block/color/BlockColorCustom.java b/src/main/java/net/minecraft/client/render/block/color/BlockColorCustom.java
new file mode 100644
index 000000000..a0fcdb374
--- /dev/null
+++ b/src/main/java/net/minecraft/client/render/block/color/BlockColorCustom.java
@@ -0,0 +1,28 @@
+package net.minecraft.client.render.block.color;
+
+import net.minecraft.client.render.colorizer.Colorizer;
+import net.minecraft.core.world.WorldSource;
+
+public class BlockColorCustom extends BlockColor {
+
+	public Colorizer colorizer;
+	
+	public BlockColorCustom(Colorizer colorizer) {
+		this.colorizer = colorizer;
+		
+		if(colorizer == null) {
+			throw new NullPointerException();
+		}
+	}
+	
+	@Override
+	public int getFallbackColor(int meta) {
+		return colorizer.getDefaultColor(1.0, 0.7);
+	}
+
+	@Override
+	public int getWorldColor(WorldSource world, int x, int y, int z) {
+		return colorizer.getColor(world, x, y, z);
+	}
+
+}
diff --git a/src/main/java/net/minecraft/client/render/block/color/BlockColorDispatcher.java b/src/main/java/net/minecraft/client/render/block/color/BlockColorDispatcher.java
index 1ff86d6e8..5174775ed 100644
--- a/src/main/java/net/minecraft/client/render/block/color/BlockColorDispatcher.java
+++ b/src/main/java/net/minecraft/client/render/block/color/BlockColorDispatcher.java
@@ -1,5 +1,6 @@
 package net.minecraft.client.render.block.color;
 
+import net.minecraft.client.render.colorizer.Colorizers;
 import net.minecraft.client.util.dispatch.Dispatcher;
 import net.minecraft.core.block.Block;
 
@@ -16,28 +17,28 @@ public final class BlockColorDispatcher
 
     private BlockColorDispatcher()
     {
-        addDispatch(Block.algae, new BlockColorGrass());
-        addDispatch(Block.fluidWaterStill, new BlockColorWater());
-        addDispatch(Block.fluidWaterFlowing, new BlockColorWater());
-        addDispatch(Block.grass, new BlockColorGrass());
-        addDispatch(Block.layerLeavesOak, new BlockColorLeavesOak());
-        addDispatch(Block.leavesBirch, new BlockColorLeaves("birch"));
-        addDispatch(Block.leavesCherry, new BlockColorLeaves("cherry"));
-        addDispatch(Block.leavesCherryFlowering, new BlockColorLeaves("cherry"));
-        addDispatch(Block.leavesEucalyptus, new BlockColorLeaves("eucalyptus"));
-        addDispatch(Block.leavesCacao, new BlockColorLeaves("cocoa"));
-        addDispatch(Block.leavesOak, new BlockColorLeavesOak());
-        addDispatch(Block.leavesPine, new BlockColorLeaves("pine"));
-        addDispatch(Block.leavesShrub, new BlockColorLeaves("shrub"));
-        addDispatch(Block.leavesThorn, new BlockColorLeaves("caatinga"));
-        addDispatch(Block.leavesPalm, new BlockColorLeaves("palm"));
-        addDispatch(Block.mossStone, new BlockColorGrass());
-        addDispatch(Block.mossBasalt, new BlockColorGrass());
-        addDispatch(Block.mossLimestone, new BlockColorGrass());
-        addDispatch(Block.mossGranite, new BlockColorGrass());
+        addDispatch(Block.algae, new BlockColorCustom(Colorizers.grass));
+        addDispatch(Block.fluidWaterStill, new BlockColorCustom(Colorizers.water));
+        addDispatch(Block.fluidWaterFlowing, new BlockColorCustom(Colorizers.water));
+        addDispatch(Block.grass, new BlockColorCustom(Colorizers.grass));
+        addDispatch(Block.layerLeavesOak, new BlockColorLeavesOak(Colorizers.oak));
+        addDispatch(Block.leavesBirch, new BlockColorCustom(Colorizers.birch));
+        addDispatch(Block.leavesCherry, new BlockColorCustom(Colorizers.cherry));
+        addDispatch(Block.leavesCherryFlowering, new BlockColorCustom(Colorizers.cherry));
+        addDispatch(Block.leavesEucalyptus, new BlockColorCustom(Colorizers.eucalyptus));
+        addDispatch(Block.leavesCacao, new BlockColorCustom(Colorizers.cacao));
+        addDispatch(Block.leavesOak, new BlockColorLeavesOak(Colorizers.oak));
+        addDispatch(Block.leavesPine, new BlockColorCustom(Colorizers.pine));
+        addDispatch(Block.leavesShrub, new BlockColorCustom(Colorizers.shrub));
+        addDispatch(Block.leavesThorn, new BlockColorCustom(Colorizers.thorn));
+        addDispatch(Block.leavesPalm, new BlockColorCustom(Colorizers.palm));
+        addDispatch(Block.mossStone, new BlockColorCustom(Colorizers.grass));
+        addDispatch(Block.mossBasalt, new BlockColorCustom(Colorizers.grass));
+        addDispatch(Block.mossLimestone, new BlockColorCustom(Colorizers.grass));
+        addDispatch(Block.mossGranite, new BlockColorCustom(Colorizers.grass));
         addDispatch(Block.wireRedstone, new BlockColorRedstoneWire());
-        addDispatch(Block.tallgrass, new BlockColorGrass());
-        addDispatch(Block.tallgrassFern, new BlockColorGrass());
+        addDispatch(Block.tallgrass, new BlockColorCustom(Colorizers.grass));
+        addDispatch(Block.tallgrassFern, new BlockColorCustom(Colorizers.grass));
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/client/render/block/color/BlockColorGrass.java b/src/main/java/net/minecraft/client/render/block/color/BlockColorGrass.java
deleted file mode 100644
index ee3d07934..000000000
--- a/src/main/java/net/minecraft/client/render/block/color/BlockColorGrass.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package net.minecraft.client.render.block.color;
-
-import net.minecraft.client.render.colorizer.ColorizerGrass;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.noise.ImprovedNoise;
-import net.minecraft.core.world.season.Season;
-import net.minecraft.core.world.season.Seasons;
-
-import java.util.Random;
-
-public class BlockColorGrass
-    extends BlockColor
-{
-    protected static ImprovedNoise grassColorPerlin = new ImprovedNoise(new Random(0));
-
-    @Override
-    public int getFallbackColor(int meta)
-    {
-        return ColorizerGrass.grassMap.getGrassColor(0.5, 0.5);
-    }
-
-    @Override
-    public int getWorldColor(WorldSource world, int x, int y, int z) {
-        double localTemperature = world.getBlockTemperature(x, z);
-        double localHumidity = world.getBlockHumidity(x, z);
-        return ColorizerGrass.grassMap.getGrassColor(localTemperature, localHumidity);
-    }
-}
diff --git a/src/main/java/net/minecraft/client/render/block/color/BlockColorLeaves.java b/src/main/java/net/minecraft/client/render/block/color/BlockColorLeaves.java
deleted file mode 100644
index 66a20d732..000000000
--- a/src/main/java/net/minecraft/client/render/block/color/BlockColorLeaves.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package net.minecraft.client.render.block.color;
-
-import net.minecraft.client.render.colorizer.ColorProperties;
-import net.minecraft.client.render.colorizer.ColorizerFoliage;
-import net.minecraft.client.render.colorizer.LeavesColorProperties;
-import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.season.Season;
-
-public class BlockColorLeaves
-    extends BlockColor
-{
-    protected final String colorId;
-
-    public BlockColorLeaves(String colorId)
-    {
-        this.colorId = colorId;
-    }
-
-    @Override
-    public int getFallbackColor(int meta)
-    {
-        LeavesColorProperties color = ColorProperties.getLeavesColor(colorId);
-        if (color == null) return 0xFFFFFF;
-        return ColorProperties.fRGB2iRGB(color.inventoryR, color.inventoryG, color.inventoryB);
-    }
-
-    @Override
-    public int getWorldColor(WorldSource world, int x, int y, int z)
-    {
-        LeavesColorProperties color = ColorProperties.getLeavesColor(colorId);
-        if (color == null) return 0xFFFFFF;
-        int foliageColor = ColorProperties.fRGB2iRGB(color.inventoryR, color.inventoryG, color.inventoryB);
-        if (world != null)
-        {
-            double temp = world.getBlockTemperature(x, z);
-            double hum = world.getBlockHumidity(x, z);
-            Season season = world.getSeasonManager().getCurrentSeason();
-            if (season != null)
-            {
-                float progress = world.getSeasonManager().getSeasonProgress();
-                foliageColor = ColorizerFoliage.getSeasonalColor(season, progress, temp, hum, color);
-            }
-        }
-
-        return foliageColor;
-    }
-}
diff --git a/src/main/java/net/minecraft/client/render/block/color/BlockColorLeavesOak.java b/src/main/java/net/minecraft/client/render/block/color/BlockColorLeavesOak.java
index b002e3780..4191dae30 100644
--- a/src/main/java/net/minecraft/client/render/block/color/BlockColorLeavesOak.java
+++ b/src/main/java/net/minecraft/client/render/block/color/BlockColorLeavesOak.java
@@ -1,53 +1,42 @@
 package net.minecraft.client.render.block.color;
 
-import net.minecraft.client.render.colorizer.ColorProperties;
-import net.minecraft.client.render.colorizer.ColorizerFoliage;
-import net.minecraft.client.render.colorizer.LeavesColorProperties;
+import java.util.Random;
+
+import net.minecraft.client.render.colorizer.Colorizer;
 import net.minecraft.core.world.WorldSource;
 import net.minecraft.core.world.noise.ImprovedNoise;
 import net.minecraft.core.world.season.Season;
 import net.minecraft.core.world.season.Seasons;
 
-import java.util.Random;
-
-public class BlockColorLeavesOak
-    extends BlockColorLeaves
-{
-    private static ImprovedNoise fallColorPerlin = new ImprovedNoise(new Random(0));
-
-    public BlockColorLeavesOak()
-    {
-        super("oak");
-    }
-
-    @Override
-    public int getWorldColor(WorldSource world, int x, int y, int z)
-    {
-        LeavesColorProperties color = ColorProperties.getLeavesColor(colorId);
-        if (color == null) return 0xFFFFFF;
-        int foliageColor = ColorProperties.fRGB2iRGB(color.inventoryR, color.inventoryG, color.inventoryB);
-        if (world != null)
-        {
-            double temp = world.getBlockTemperature(x, z);
-            double hum = world.getBlockHumidity(x, z);
-            Season season = world.getSeasonManager().getCurrentSeason();
-            if (season != null)
-            {
-                float progress = world.getSeasonManager().getSeasonProgress();
-                foliageColor = ColorizerFoliage.getSeasonalColor(season, progress, temp, hum, color, true);
-                if (season == Seasons.OVERWORLD_FALL)
-                {
-                    float offsetIntensity = 1 - Math.abs((progress * 2) - 1);
-                    float green = ((foliageColor & 0x00FF00) >> 8) / 255F;
-                    float greenOffset = (float)fallColorPerlin.getValue(x / 10D, y / 10D, z / 10D) * offsetIntensity * 0.5f;
-                    if (green + greenOffset > 0.8f) greenOffset = 0.8f - green;
-                    if (green + greenOffset < 0.0f) greenOffset = -green;
-                    int newGreen = ((int)((green + greenOffset) * 255)) & 0xFF;
-                    foliageColor &= 0xFF00FF;
-                    foliageColor |= (newGreen << 8);
-                }
-            }
-        }
-        return foliageColor;
-    }
+public class BlockColorLeavesOak extends BlockColorCustom {
+	
+	private static ImprovedNoise fallColorPerlin = new ImprovedNoise(new Random(0));
+	
+	public BlockColorLeavesOak(Colorizer colorizer) {
+		super(colorizer);
+	}
+	
+	@Override
+	public int getWorldColor(WorldSource world, int x, int y, int z) {
+		int color = super.getWorldColor(world, x, y, z);
+		
+		Season season = world.getSeasonManager().getCurrentSeason();
+		if(season != null) {
+			float progress = world.getSeasonManager().getSeasonProgress();
+			if(season == Seasons.OVERWORLD_FALL) {
+				float offsetIntensity = 1 - Math.abs((progress * 2) - 1);
+				float green = ((color & 0x00FF00) >> 8) / 255F;
+				float greenOffset = (float) fallColorPerlin.getValue(x / 10D, y / 10D, z / 10D) * offsetIntensity * 0.5f;
+				if(green + greenOffset > 0.8f)
+					greenOffset = 0.8f - green;
+				if(green + greenOffset < 0.0f)
+					greenOffset = -green;
+				int newGreen = ((int) ((green + greenOffset) * 255)) & 0xFF;
+				color &= 0xFF00FF;
+				color |= (newGreen << 8);
+			}
+		}
+		
+		return color;
+	}
 }
diff --git a/src/main/java/net/minecraft/client/render/block/color/BlockColorTallGrass.java b/src/main/java/net/minecraft/client/render/block/color/BlockColorTallGrass.java
index fc4131b05..24e967e4b 100644
--- a/src/main/java/net/minecraft/client/render/block/color/BlockColorTallGrass.java
+++ b/src/main/java/net/minecraft/client/render/block/color/BlockColorTallGrass.java
@@ -1,34 +1,38 @@
 package net.minecraft.client.render.block.color;
 
-import net.minecraft.core.block.Block;
-import net.minecraft.client.render.colorizer.ColorizerGrass;
+import java.util.Random;
+
+import net.minecraft.client.render.colorizer.Colorizer;
+import net.minecraft.client.render.colorizer.Colorizers;
 import net.minecraft.core.world.WorldSource;
-import net.minecraft.core.world.biome.Biomes;
-import net.minecraft.core.world.season.Season;
-import net.minecraft.core.world.season.Seasons;
-
-public class BlockColorTallGrass
-    extends BlockColorGrass
-{
-    @Override
-    public int getWorldColor(WorldSource world, int x, int y, int z)
-    {
-
-        double localTemperature = world.getBlockTemperature(x, z);
-        double localHumidity = world.getBlockHumidity(x, z);
-
-        long l1 = x * 0x2fc20fL + z * 0x5d8875L + y;
-        l1 = l1 * l1 * 0x285b825L + l1 * 11L;
-        int xO = (int)((long) x + (l1 >> 14 & 31L));
-        int yO = (int)((long) y + (l1 >> 19 & 31L));
-        int zO = (int)((long) z + (l1 >> 24 & 31L));
-
-        float offsetT = (float) grassColorPerlin.getValue(xO / 32D, yO / 32D, z / 32D) / 2.5F;
-        float offsetH = (float) grassColorPerlin.getValue(x / 32D, yO / 32D, zO / 32D) / 2.5F;
-
-        localTemperature += offsetT;
-        localHumidity += offsetH;
-
-        return ColorizerGrass.defaultColor.getGrassColor(localTemperature, localHumidity);
-    }
+import net.minecraft.core.world.noise.ImprovedNoise;
+
+public class BlockColorTallGrass extends BlockColorCustom {
+	
+	protected static ImprovedNoise grassColorPerlin = new ImprovedNoise(new Random(0));
+	
+	public BlockColorTallGrass(Colorizer colorizer) {
+		super(colorizer);
+	}
+	
+	@Override
+	public int getWorldColor(WorldSource world, int x, int y, int z) {
+
+		double localTemperature = world.getBlockTemperature(x, z);
+		double localHumidity = world.getBlockHumidity(x, z);
+
+		long l1 = x * 0x2fc20fL + z * 0x5d8875L + y;
+		l1 = l1 * l1 * 0x285b825L + l1 * 11L;
+		int xO = (int) ((long) x + (l1 >> 14 & 31L));
+		int yO = (int) ((long) y + (l1 >> 19 & 31L));
+		int zO = (int) ((long) z + (l1 >> 24 & 31L));
+
+		float offsetT = (float) grassColorPerlin.getValue(xO / 32D, yO / 32D, z / 32D) / 2.5F;
+		float offsetH = (float) grassColorPerlin.getValue(x / 32D, yO / 32D, zO / 32D) / 2.5F;
+
+		localTemperature += offsetT;
+		localHumidity += offsetH;
+
+		return Colorizers.grass.getColor(localTemperature, localHumidity);
+	}
 }
diff --git a/src/main/java/net/minecraft/client/render/block/color/BlockColorWater.java b/src/main/java/net/minecraft/client/render/block/color/BlockColorWater.java
deleted file mode 100644
index 100362b2c..000000000
--- a/src/main/java/net/minecraft/client/render/block/color/BlockColorWater.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package net.minecraft.client.render.block.color;
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.render.colorizer.ColorizerWater;
-import net.minecraft.core.world.WorldSource;
-
-public class BlockColorWater
-    extends BlockColor
-{
-	private final Minecraft mc = Minecraft.getMinecraft(this);
-	
-    @Override
-    public int getFallbackColor(int meta)
-    {
-        if (mc.gameSettings.biomeWater.value)
-        {
-            return ColorizerWater.getWaterColor(0.5, 0.5);
-        }
-
-        return 0xFFFFFF;
-    }
-
-    @Override
-    public int getWorldColor(WorldSource world, int x, int y, int z)
-    {
-        if (world != null) {
-            if (mc.gameSettings.biomeWater.value)
-            {
-                double temp = world.getBlockTemperature(x, z);
-                double hum = world.getBlockHumidity(x, z);
-                return ColorizerWater.getWaterColor(temp, hum);
-            }
-        }
-        return 0xFFFFFF;
-    }
-}
diff --git a/src/main/java/net/minecraft/client/render/colorizer/ColorMap.java b/src/main/java/net/minecraft/client/render/colorizer/ColorMap.java
new file mode 100644
index 000000000..3d7ff8b35
--- /dev/null
+++ b/src/main/java/net/minecraft/client/render/colorizer/ColorMap.java
@@ -0,0 +1,29 @@
+package net.minecraft.client.render.colorizer;
+
+import net.minecraft.core.util.helper.MathHelper;
+
+public class ColorMap {
+	
+	public final Colorizer colorizer;
+	public final int[] buffer = new int[0x10000];
+	
+	public ColorMap(Colorizer colorizer) {
+		this.colorizer = colorizer;
+		
+		for(int i=0; i < buffer.length; i++) {
+			buffer[i] = 0xFFFFFFFF;
+		}
+	}
+	
+	public int getColor(double temp, double humid) {
+		temp = MathHelper.clamp(temp, 0.0, 1.0);
+		humid = MathHelper.clamp(humid, 0.0, 1.0);
+		
+		humid *= temp;	
+		
+		int x = (int) ((1.0 - temp) * 255.0);
+		int y = (int) ((1.0 - humid) * 255.0);
+		return buffer[y << 8 | x];
+	}
+
+}
diff --git a/src/main/java/net/minecraft/client/render/colorizer/ColorProperties.java b/src/main/java/net/minecraft/client/render/colorizer/ColorProperties.java
deleted file mode 100644
index 0fd2cab3c..000000000
--- a/src/main/java/net/minecraft/client/render/colorizer/ColorProperties.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package net.minecraft.client.render.colorizer;
-
-import net.minecraft.core.world.season.SeasonColorProperties;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
-public class ColorProperties
-{
-    private final static Map<String, SeasonColorProperties> seasonColors = new HashMap<>();
-    private final static Map<String, LeavesColorProperties> leavesColors = new HashMap<>();
-
-    public static void loadColors(Properties prop)
-    {
-        registerSeasonColor("spring", prop);
-        registerSeasonColor("summer", prop);
-        registerSeasonColor("fall", prop);
-        registerSeasonColor("winter", prop);
-
-        registerLeavesColor("oak", prop);
-        registerLeavesColor("pine", prop);
-        registerLeavesColor("birch", prop);
-        registerLeavesColor("cherry", prop);
-        registerLeavesColor("eucalyptus", prop);
-        registerLeavesColor("shrub", prop);
-        registerLeavesColor("caatinga", prop);
-        registerLeavesColor("cocoa", prop);
-        registerLeavesColor("palm", prop);
-    }
-
-    private static void registerSeasonColor(String name, Properties prop)
-    {
-        seasonColors.put(name, new SeasonColorProperties(name, prop));
-    }
-
-    private static void registerLeavesColor(String name, Properties prop)
-    {
-        leavesColors.put(name, new LeavesColorProperties(name, prop));
-    }
-
-    public static SeasonColorProperties getSeasonColor(String name)
-    {
-        return seasonColors.get(name);
-    }
-
-    public static LeavesColorProperties getLeavesColor(String name)
-    {
-        return leavesColors.get(name);
-    }
-
-    public static int fRGB2iRGB(float r, float g, float b)
-    {
-        return ((int)(r * 255) << 16) | ((int)(g * 255) << 8) | ((int)(b * 255) << 0);
-    }
-
-}
diff --git a/src/main/java/net/minecraft/client/render/colorizer/Colorizer.java b/src/main/java/net/minecraft/client/render/colorizer/Colorizer.java
new file mode 100644
index 000000000..838a2588c
--- /dev/null
+++ b/src/main/java/net/minecraft/client/render/colorizer/Colorizer.java
@@ -0,0 +1,128 @@
+package net.minecraft.client.render.colorizer;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.core.util.helper.MathHelper;
+import net.minecraft.core.world.WorldSource;
+import net.minecraft.core.world.season.Season;
+import net.minecraft.core.world.season.Seasons;
+
+public class Colorizer {
+	
+	public final String name;
+	
+	private ColorMap defaultColor;
+	private Map<Season, ColorMap> seasonalColormaps;
+	private ColorMap currentColor;
+	private boolean enabled = false;
+	
+	public Colorizer(String name) {
+		this.name = name;
+	}
+	
+	public void setup(Minecraft minecraft, List<Season> seasons) {
+		this.defaultColor = new ColorMap(this);
+		this.seasonalColormaps = new HashMap<>();
+		this.currentColor = new ColorMap(this);
+		
+		if(Colorizers.loadColorData(defaultColor, "default")) {
+			this.enabled = true;
+			for(int i=0; i < seasons.size(); i++) {
+				Season season = seasons.get(i);
+				if(season == Seasons.NULL) {
+					continue;
+				}
+				
+				String seasonName = season.getId().replace('.', '_');
+				ColorMap colorMap = new ColorMap(this);
+				
+				if(Colorizers.loadColorData(colorMap, seasonName)) {
+					this.seasonalColormaps.put(season, colorMap);
+				}
+			}
+		}else {
+			this.enabled = false;
+		}
+	}
+	
+	public ColorMap getColormapForSeason(Season season) {
+		ColorMap colorMap = this.seasonalColormaps.get(season);
+		if(colorMap == null) {
+			return defaultColor;
+		}
+		return colorMap;
+	}
+	
+	public void update(Season season) {
+		ColorMap seasonColors = getColormapForSeason(season);
+		for(int i=0; i < currentColor.buffer.length; i++) {
+			currentColor.buffer[i] = seasonColors.buffer[i];
+		}
+	}
+	
+	public void update(Season season1, Season season2, float blendFactor) {
+		ColorMap seasonColors1 = getColormapForSeason(season1);
+		ColorMap seasonColors2 = getColormapForSeason(season2);
+		
+		for(int i=0; i < currentColor.buffer.length; i++) {
+			currentColor.buffer[i] = blendColor(seasonColors1.buffer[i], seasonColors2.buffer[i], blendFactor);
+		}
+	}
+	
+	public int getDefaultColor(double temperature, double humidity) {
+		if(!enabled) {
+			return 0xFFFFFFFF;
+		}
+		
+		return defaultColor.getColor(temperature, humidity);
+	}
+	
+	public int getColor(WorldSource world, int x, int y, int z) {
+		if(!enabled) {
+			return 0xFFFFFFFF;
+		}
+		
+		double temperature = world.getBlockTemperature(x, z);
+		double humidity = world.getBlockHumidity(x, z);
+		
+		return getColor(temperature, humidity);
+	}
+	
+	public int getColor(double temperature, double humidity) {
+		if(!enabled) {
+			return 0xFFFFFFFF;
+		}
+		
+		return currentColor.getColor(temperature, humidity);
+	}
+	
+	public boolean isEnabled() {
+		return enabled;
+	}
+	
+	public static int blendColor(int color1, int color2, float blend) {
+		float blend1 = 1.0f - blend;
+		
+		int r1 = (color1 >> 16) & 0xFF;
+		int g1 = (color1 >>  8) & 0xFF;
+		int b1 = (color1 >>  0) & 0xFF;
+		
+		int r2 = (color2 >> 16) & 0xFF;
+		int g2 = (color2 >>  8) & 0xFF;
+		int b2 = (color2 >>  0) & 0xFF;
+		
+		int r = (int)(r1 * blend1 + r2 * blend);
+		int g = (int)(g1 * blend1 + g2 * blend);
+		int b = (int)(b1 * blend1 + b2 * blend);
+		
+		r = MathHelper.clamp(r, 0, 255);
+		g = MathHelper.clamp(g, 0, 255);
+		b = MathHelper.clamp(b, 0, 255);
+		
+		return r << 16 | g << 8 | b; 
+	}
+
+}
diff --git a/src/main/java/net/minecraft/client/render/colorizer/ColorizerFoliage.java b/src/main/java/net/minecraft/client/render/colorizer/ColorizerFoliage.java
deleted file mode 100644
index 429b5a1b3..000000000
--- a/src/main/java/net/minecraft/client/render/colorizer/ColorizerFoliage.java
+++ /dev/null
@@ -1,157 +0,0 @@
-package net.minecraft.client.render.colorizer;
-
-
-import net.minecraft.core.world.season.Season;
-import net.minecraft.core.world.season.Seasons;
-
-public class ColorizerFoliage
-{
-
-    public ColorizerFoliage()
-    {
-    }
-
-    public static void updateColorData(int ai[])
-    {
-        foliageBuffer = ai;
-    }
-
-    private static int getFoliageColor(double d, double d1)
-    {
-        d1 *= d;
-        int i = (int)((1.0D - d) * 255D);
-        int j = (int)((1.0D - d1) * 255D);
-        return foliageBuffer[j << 8 | i];
-    }
-
-	private static int getPeakSeasonalColor(Season season, double temp, double hum, LeavesColorProperties lcp)
-	{
-		int myColor = ColorProperties.fRGB2iRGB(lcp.inventoryR, lcp.inventoryG, lcp.inventoryB);
-
-		if (season == Seasons.OVERWORLD_SPRING)
-		{
-			if (lcp.overrideSpring)
-			{
-				myColor = ColorProperties.fRGB2iRGB(lcp.springR, lcp.springG, lcp.springB);
-			}
-			else
-			{
-				myColor = getFoliageColor(temp, hum);
-			}
-		}
-		else if (season == Seasons.OVERWORLD_SUMMER)
-		{
-			if (lcp.overrideSummer)
-			{
-				myColor = ColorProperties.fRGB2iRGB(lcp.summerR, lcp.summerG, lcp.summerB);
-			}
-			else
-			{
-				myColor = getFoliageColor(temp, hum);
-			}
-		}
-		else if (season == Seasons.OVERWORLD_FALL)
-		{
-			if (lcp.overrideFall)
-			{
-				myColor = ColorProperties.fRGB2iRGB(lcp.fallR, lcp.fallG, lcp.fallB);
-			}
-			else
-			{
-				myColor = getFoliageColor(temp, hum);
-			}
-		}
-		else if (season == Seasons.OVERWORLD_WINTER || season == Seasons.OVERWORLD_WINTER_ENDLESS)
-		{
-			if (lcp.overrideWinter)
-			{
-				myColor = ColorProperties.fRGB2iRGB(lcp.winterR, lcp.winterG, lcp.winterB);
-			}
-			else
-			{
-				myColor = getFoliageColor(temp, hum);
-			}
-		}
-
-		return myColor;
-	}
-
-	public static int getSeasonalColor(Season season, float progress, double temp, double hum, LeavesColorProperties lcp)
-	{
-		return getSeasonalColor(season, progress, temp, hum, lcp, false);
-	}
-
-	public static int getSeasonalColor(Season season, float progress, double temp, double hum, LeavesColorProperties lcp, boolean applySeasonalTransform)
-	{
-		int myColor = getPeakSeasonalColor(season, temp, hum, lcp);
-		Season otherSeason;
-		int otherColor = getPeakSeasonalColor(season, temp, hum, lcp);
-
-		float blend = Math.abs(progress - 0.5f);
-
-		if (season == Seasons.OVERWORLD_SPRING)
-		{
-			if (progress < 0.5f)
-			{
-				otherSeason = Seasons.OVERWORLD_WINTER;
-			}
-			else
-			{
-				otherSeason = Seasons.OVERWORLD_SUMMER;
-			}
-		}
-		else if (season == Seasons.OVERWORLD_SUMMER)
-		{
-			if (progress < 0.5f)
-			{
-				otherSeason = Seasons.OVERWORLD_SPRING;
-			}
-			else
-			{
-				otherSeason = Seasons.OVERWORLD_FALL;
-			}
-		}
-		else if (season == Seasons.OVERWORLD_FALL)
-		{
-			if (progress < 0.5f)
-			{
-				otherSeason = Seasons.OVERWORLD_SUMMER;
-			}
-			else
-			{
-				otherSeason = Seasons.OVERWORLD_WINTER;
-			}
-		}
-		else if (season == Seasons.OVERWORLD_WINTER)
-		{
-			if (progress < 0.5f)
-			{
-				otherSeason = Seasons.OVERWORLD_FALL;
-			}
-			else
-			{
-				otherSeason = Seasons.OVERWORLD_SPRING;
-			}
-		}
-		else
-		{
-			otherSeason = season;
-		}
-
-		if (otherSeason != null)
-		{
-			otherColor = getPeakSeasonalColor(otherSeason, temp, hum, lcp);
-
-			if (applySeasonalTransform)
-			{
-				myColor = season.modifyFoliageColorizer(myColor, otherSeason, blend);
-			}
-		}
-
-		return Season.blendColors(myColor, otherColor, blend);
-
-	}
-
-    private static int foliageBuffer[] = new int[0x10000];
-
-}
diff --git a/src/main/java/net/minecraft/client/render/colorizer/ColorizerGrass.java b/src/main/java/net/minecraft/client/render/colorizer/ColorizerGrass.java
deleted file mode 100644
index a00534d69..000000000
--- a/src/main/java/net/minecraft/client/render/colorizer/ColorizerGrass.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package net.minecraft.client.render.colorizer;
-
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.core.world.World;
-import net.minecraft.core.world.season.Season;
-import net.minecraft.core.world.season.Seasons;
-
-public class ColorizerGrass
-{
-    private static Minecraft mc = Minecraft.getMinecraft(ColorizerGrass.class);
-    public ColorizerGrass()
-    {
-    }
-
-    public static void update(boolean force){
-        World world = mc.theWorld;
-        if(world == null) {
-            lastTickWorld = null;
-            return;
-        }
-        Season season = world.getSeasonManager().getCurrentSeason();
-        int dayInSeason = world.seasonManager.getDayInSeason();
-        float progress = world.getSeasonManager().getSeasonProgress();
-        boolean update = force || lastTickWorld != world || lastTickSeason != season || lastTickDayInSeason != dayInSeason;
-        if(update) {
-            lastTickSeason = season;
-            lastTickDayInSeason = dayInSeason;
-            lastTickWorld = world;
-            if (season == null) {
-                grassMap.updateColorData(defaultColor.buffer);
-            } else {
-                updateColor(season, progress > 0.5f ? world.getSeasonManager().getNextSeason() : world.getSeasonManager().getPreviousSeason(), Math.abs(progress));
-            }
-        }
-    }
-
-    private static void updateColor(Season season1, Season season2, float blend) {
-        GrassColorMap colormap1 = getSeasonalColorizer(season1);
-        GrassColorMap colormap2 = getSeasonalColorizer(season2);
-        int[] buffer1 = colormap1.buffer;
-        int[] buffer2 = colormap2.buffer;
-        int[] data = grassMap.buffer;
-
-        for(int i = 0; i < data.length; ++i) {
-            data[i] = Season.blendColors(buffer1[i], buffer2[i], blend);
-        }
-    }
-
-    private static GrassColorMap getSeasonalColorizer(Season season) {
-        if (season == Seasons.OVERWORLD_SPRING) {
-            return spring;
-        } else if (season == Seasons.OVERWORLD_SUMMER) {
-            return summer;
-        } else if (season == Seasons.OVERWORLD_FALL) {
-            return fall;
-        } else if (season == Seasons.OVERWORLD_WINTER) {
-            return winter;
-        } else {
-            return grassMap;
-        }
-    }
-    public static GrassColorMap defaultColor = new GrassColorMap();
-    public static GrassColorMap spring = new GrassColorMap();
-    public static GrassColorMap summer = new GrassColorMap();
-    public static GrassColorMap fall = new GrassColorMap();
-    public static GrassColorMap winter = new GrassColorMap();
-    public static GrassColorMap grassMap = new GrassColorMap();
-    private static World lastTickWorld;
-    private static Season lastTickSeason;
-    private static float lastTickDayInSeason;
-
-}
diff --git a/src/main/java/net/minecraft/client/render/colorizer/ColorizerWater.java b/src/main/java/net/minecraft/client/render/colorizer/ColorizerWater.java
deleted file mode 100644
index 49fbcae1b..000000000
--- a/src/main/java/net/minecraft/client/render/colorizer/ColorizerWater.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package net.minecraft.client.render.colorizer;
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.core.world.Dimension;
-
-public class ColorizerWater {
-
-	private static Minecraft mc = Minecraft.getMinecraft(ColorizerWater.class);
-	private static int colorData[] = new int[65536];
-
-	public static void updateColorData(int[] colorData) {
-		ColorizerWater.colorData = colorData;
-	}
-
-	public static int getWaterColor(double temperature, double humidity) {
-		try {
-			if (mc.gameSettings.biomeWater.value) {
-
-				if(mc.theWorld.dimension == Dimension.nether){
-					return 0XF54242;
-				}
-
-				humidity *= temperature;
-				
-				int i = (int) ((1.0 - temperature) * 255D);
-				int j = (int) ((1.0 - humidity) * 255D);
-				
-				return colorData[j << 8 | i];
-			} else {
-				return 0xffffffff;
-			}
-		} catch (Throwable e) {
-			return 0xffffffff;
-		}
-	}
-
-}
diff --git a/src/main/java/net/minecraft/client/render/colorizer/Colorizers.java b/src/main/java/net/minecraft/client/render/colorizer/Colorizers.java
new file mode 100644
index 000000000..7ee772e51
--- /dev/null
+++ b/src/main/java/net/minecraft/client/render/colorizer/Colorizers.java
@@ -0,0 +1,212 @@
+package net.minecraft.client.render.colorizer;
+
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.imageio.ImageIO;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.core.Global;
+import net.minecraft.core.util.helper.MathHelper;
+import net.minecraft.core.world.World;
+import net.minecraft.core.world.season.Season;
+import net.minecraft.core.world.season.SeasonManagerCycle;
+import net.minecraft.core.world.season.Seasons;
+
+public class Colorizers {
+	
+	public static Minecraft mc;
+	
+	private static List<Colorizer> allColorizers = null;
+
+	public static Colorizer grass;
+	public static Colorizer water;
+	public static Colorizer sky;
+	public static Colorizer fog;
+	public static Colorizer oak;
+	public static Colorizer birch;
+	public static Colorizer pine;
+	public static Colorizer cherry;
+	public static Colorizer shrub;
+	public static Colorizer eucalyptus;
+	public static Colorizer cacao;
+	public static Colorizer thorn;
+	public static Colorizer palm;
+	
+	private static Season lastSeason;
+	private static float lastSeasonProgress;
+	
+	private static float fadeDuration = 1.0f;
+	
+	public static void init(Minecraft minecraft) {
+		mc = minecraft;
+		
+		registerColorizers();
+	}
+	
+	public static void reload() {
+		List<Season> seasons = Seasons.getAllSeasons();
+		
+		for(int i=0; i < allColorizers.size(); i++) {
+			allColorizers.get(i).setup(mc, seasons);
+		}
+		
+        update(true);
+	}
+	
+	public static void registerColorizers() {
+		allColorizers = new ArrayList<>();
+		
+		grass = add(new Colorizer("grass"));
+		water = add(new Colorizer("water"));
+		sky = add(new Colorizer("sky"));
+		fog = add(new Colorizer("fog"));
+		oak = add(new Colorizer("oak"));
+		birch = add(new Colorizer("birch"));
+		pine = add(new Colorizer("pine"));
+		cherry = add(new Colorizer("cherry"));
+		shrub = add(new Colorizer("shrub"));
+		eucalyptus = add(new Colorizer("eucalyptus"));
+		cacao = add(new Colorizer("cacao"));
+		thorn = add(new Colorizer("thorn"));
+		palm = add(new Colorizer("palm"));
+	}
+	
+	public static void update(boolean force) {
+		World world = mc.theWorld;
+		if(world == null) {
+			return;
+		}
+		
+		Season currentSeason = world.seasonManager.getCurrentSeason();
+		float seasonProgress = getSeasonProgress(world);
+		
+		boolean update;
+		if(force) {
+			update = true;
+		}else if(currentSeason != lastSeason) {
+			update = true;
+		}else if(seasonProgress != lastSeasonProgress) {
+			update = true;
+		}else {
+			update = false;
+		}
+		
+		if(!update) {
+			return;
+		}
+		
+		lastSeason = currentSeason;
+		lastSeasonProgress = seasonProgress;
+		
+		System.out.println("Updating Colorizers");
+		
+		Season season1, season2;
+		float blendFactor;
+		
+		float fadeDurationInverse = 1.0f - fadeDuration;
+		
+		if(seasonProgress < 0.5f) {
+			season1 = world.getSeasonManager().getPreviousSeason();
+			season2 = currentSeason;
+			blendFactor = seasonProgress + 0.5f; // 0.5 -> 1.0
+			if(fadeDuration == 0.0f) {
+				blendFactor = 1.0f;
+			}else {
+				blendFactor = seasonProgress * 2.0f; // 0.0 -> 1.0
+				blendFactor /= fadeDuration;
+				blendFactor = MathHelper.clamp(blendFactor, 0.0f, 1.0f); // 0.0 -> 1.0
+				blendFactor = blendFactor * 0.5f + 0.5f;
+			}
+		}else {
+			season1 = currentSeason;
+			season2 = world.getSeasonManager().getNextSeason();
+			blendFactor = seasonProgress - 0.5f; // 0.0 -> 0.5
+			if(fadeDuration == 0.0f) {
+				blendFactor = 0.0f;
+			}else if(fadeDuration != 1.0f) {
+				blendFactor = (seasonProgress - 0.5f) * 2.0f; //0.0 -> 1.0
+				blendFactor /= fadeDurationInverse;
+				blendFactor -= (1.0f / fadeDurationInverse) * fadeDuration;
+				blendFactor = MathHelper.clamp(blendFactor, 0.0f, 1.0f); // 0.0 -> 1.0
+			}
+		}
+		
+		for(int i=0; i < allColorizers.size(); i++) {
+			allColorizers.get(i).update(season1, season2, blendFactor);
+		}
+	}
+	
+	public static Colorizer add(Colorizer colorizer) {
+		allColorizers.add(colorizer);
+		return colorizer;
+	}
+	
+	public static boolean loadColorData(ColorMap colorMap, String name) {
+		String path = "/assets/minecraft/textures/colormap/" + colorMap.colorizer.name + "/" + name + ".png";
+		
+		InputStream in = null;
+		BufferedImage image = null;
+		
+		try {
+			in = mc.texturePackList.getResourceAsStream(path);
+			if(in == null) {
+				return false;
+			}
+			image = ImageIO.read(in);
+		}catch (Exception e) {
+			throw new RuntimeException("Loading colormap: '" + name + "'", e);
+		}finally {
+			try {
+				in.close();
+			}catch (Exception e) {}
+		}
+		
+		if(image.getWidth() == 1 && image.getHeight() == 1) {
+			int rgb = image.getRGB(0, 0);
+			
+			for(int i=0; i < colorMap.buffer.length; i++) {
+				colorMap.buffer[i] = rgb;
+			}
+			
+			return true;
+		}
+		
+		if(image.getWidth() != 256 || image.getHeight() != 256) {
+			BufferedImage fixedImage = new BufferedImage(256, 256, BufferedImage.TYPE_INT_RGB);
+			Graphics g = fixedImage.getGraphics();
+			g.drawImage(image, 0, 0, 256, 256, null);
+			g.dispose();
+			image = fixedImage;
+		}
+		
+		for(int x=0; x < 256; x++) {
+			for(int y=0; y < 256; y++) {
+				int rgb = image.getRGB(x, y);
+				
+				colorMap.buffer[y << 8 | x] = rgb;
+			}
+		}
+		
+		return true;
+	}
+	
+	public static float getSeasonProgress(World world) {
+		if(world.seasonManager instanceof SeasonManagerCycle) {
+			SeasonManagerCycle seasonManager = (SeasonManagerCycle) world.seasonManager;
+			Season currentSeason = seasonManager.getCurrentSeason();
+			
+			int dayInSeason = seasonManager.getDayInSeason();
+			int dayLengthTicks = Global.DAY_LENGTH_TICKS;
+			int seasonLengthDays = seasonManager.getSeasonLengthTicks(currentSeason) / dayLengthTicks;
+			
+			return dayInSeason / (float) seasonLengthDays;
+		}
+		
+		return 0.5f;
+	}
+
+}
diff --git a/src/main/java/net/minecraft/client/render/colorizer/GrassColorMap.java b/src/main/java/net/minecraft/client/render/colorizer/GrassColorMap.java
deleted file mode 100644
index a33b38607..000000000
--- a/src/main/java/net/minecraft/client/render/colorizer/GrassColorMap.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package net.minecraft.client.render.colorizer;
-
-public class GrassColorMap {
-    public GrassColorMap()
-    {
-    }
-    public void updateColorData(int[] map)
-    {
-        buffer = map;
-    }
-
-    public int getGrassColor(double temp, double humid)
-    {
-        if (temp < 0.0D)
-            temp = 0.0D;
-        else if(temp > 1.0D)
-            temp = 1.0D;
-        if (humid < 0.0D)
-            humid = 0.0D;
-        else if(humid > 1.0D)
-            humid = 1.0D;
-
-        humid *= temp;
-
-        int x = (int)((1.0D - temp) * 255D);
-        int y = (int)((1.0D - humid) * 255D);
-        return buffer[y << 8 | x];
-    }
-
-    public int[] buffer = new int[0x10000];
-}
diff --git a/src/main/java/net/minecraft/client/render/colorizer/LeavesColorProperties.java b/src/main/java/net/minecraft/client/render/colorizer/LeavesColorProperties.java
deleted file mode 100644
index 661e3cb1c..000000000
--- a/src/main/java/net/minecraft/client/render/colorizer/LeavesColorProperties.java
+++ /dev/null
@@ -1,224 +0,0 @@
-package net.minecraft.client.render.colorizer;
-
-import java.util.Properties;
-
-public class LeavesColorProperties
-{
-    public float inventoryR;
-    public float inventoryG;
-    public float inventoryB;
-
-    public boolean overrideSpring;
-    public float springR;
-    public float springG;
-    public float springB;
-
-    public boolean overrideSummer;
-    public float summerR;
-    public float summerG;
-    public float summerB;
-
-    public boolean overrideFall;
-    public float fallR;
-    public float fallG;
-    public float fallB;
-
-    public boolean overrideWinter;
-    public float winterR;
-    public float winterG;
-    public float winterB;
-
-    public LeavesColorProperties(String name, Properties prop)
-    {
-        String sAllR = prop.getProperty("override.leaves." + name + ".all.r", null);
-        String sAllG = prop.getProperty("override.leaves." + name + ".all.g", null);
-        String sAllB = prop.getProperty("override.leaves." + name + ".all.b", null);
-
-        String sSpringR = prop.getProperty("override.leaves." + name + ".spring.r", sAllR);
-        String sSpringG = prop.getProperty("override.leaves." + name + ".spring.g", sAllG);
-        String sSpringB = prop.getProperty("override.leaves." + name + ".spring.b", sAllB);
-
-        String sSummerR = prop.getProperty("override.leaves." + name + ".summer.r", sAllR);
-        String sSummerG = prop.getProperty("override.leaves." + name + ".summer.g", sAllG);
-        String sSummerB = prop.getProperty("override.leaves." + name + ".summer.b", sAllB);
-
-        String sFallR = prop.getProperty("override.leaves." + name + ".fall.r", sAllR);
-        String sFallG = prop.getProperty("override.leaves." + name + ".fall.g", sAllG);
-        String sFallB = prop.getProperty("override.leaves." + name + ".fall.b", sAllB);
-
-        String sWinterR = prop.getProperty("override.leaves." + name + ".winter.r", sAllR);
-        String sWinterG = prop.getProperty("override.leaves." + name + ".winter.g", sAllG);
-        String sWinterB = prop.getProperty("override.leaves." + name + ".winter.b", sAllB);
-
-        String sInventoryR = prop.getProperty("override.leaves." + name + ".inventory.r", sSummerR);
-        String sInventoryG = prop.getProperty("override.leaves." + name + ".inventory.g", sSummerG);
-        String sInventoryB = prop.getProperty("override.leaves." + name + ".inventory.b", sSummerB);
-
-        if (sInventoryR == null || sInventoryG == null || sInventoryB == null)
-        {
-            inventoryR = 1.0f;
-            inventoryG = 1.0f;
-            inventoryB = 1.0f;
-        }
-        else
-        {
-            try
-            {
-                inventoryR = Float.parseFloat(sInventoryR);
-            }
-            catch (NumberFormatException e)
-            {
-                inventoryR = 1.0f;
-            }
-            try
-            {
-                inventoryG = Float.parseFloat(sInventoryG);
-            }
-            catch (NumberFormatException e)
-            {
-                inventoryG = 1.0f;
-            }
-            try
-            {
-                inventoryB = Float.parseFloat(sInventoryB);
-            }
-            catch (NumberFormatException e)
-            {
-                inventoryB = 1.0f;
-            }
-
-        }
-
-        if (sSpringR == null || sSpringG == null || sSpringB == null)
-        {
-            overrideSpring = false;
-        }
-        else
-        {
-            overrideSpring = true;
-            try
-            {
-                springR = Float.parseFloat(sSpringR);
-            }
-            catch (NumberFormatException e)
-            {
-                springR = 1.0f;
-            }
-            try
-            {
-                springG = Float.parseFloat(sSpringG);
-            }
-            catch (NumberFormatException e)
-            {
-                springG = 1.0f;
-            }
-            try
-            {
-                springB = Float.parseFloat(sSpringB);
-            }
-            catch (NumberFormatException e)
-            {
-                springB = 1.0f;
-            }
-        }
-
-        if (sSummerR == null || sSummerG == null || sSummerB == null)
-        {
-            overrideSummer = false;
-        }
-        else
-        {
-            overrideSummer = true;
-            try
-            {
-                summerR = Float.parseFloat(sSummerR);
-            }
-            catch (NumberFormatException e)
-            {
-                summerR = 1.0f;
-            }
-            try
-            {
-                summerG = Float.parseFloat(sSummerG);
-            }
-            catch (NumberFormatException e)
-            {
-                summerG = 1.0f;
-            }
-            try
-            {
-                summerB = Float.parseFloat(sSummerB);
-            }
-            catch (NumberFormatException e)
-            {
-                summerB = 1.0f;
-            }
-        }
-
-        if (sFallR == null || sFallG == null || sFallB == null)
-        {
-            overrideFall = false;
-        }
-        else
-        {
-            overrideFall = true;
-            try
-            {
-                fallR = Float.parseFloat(sFallR);
-            }
-            catch (NumberFormatException e)
-            {
-                fallR = 1.0f;
-            }
-            try
-            {
-                fallG = Float.parseFloat(sFallG);
-            }
-            catch (NumberFormatException e)
-            {
-                fallG = 1.0f;
-            }
-            try
-            {
-                fallB = Float.parseFloat(sFallB);
-            }
-            catch (NumberFormatException e)
-            {
-                fallB = 1.0f;
-            }
-        }
-
-        if (sWinterR == null || sWinterG == null || sWinterB == null)
-        {
-            overrideWinter = false;
-        }
-        else
-        {
-            overrideWinter = true;
-            try
-            {
-                winterR = Float.parseFloat(sWinterR);
-            }
-            catch (NumberFormatException e)
-            {
-                winterR = 1.0f;
-            }
-            try
-            {
-                winterG = Float.parseFloat(sWinterG);
-            }
-            catch (NumberFormatException e)
-            {
-                winterG = 1.0f;
-            }
-            try
-            {
-                winterB = Float.parseFloat(sWinterB);
-            }
-            catch (NumberFormatException e)
-            {
-                winterB = 1.0f;
-            }
-        }
-    }
-}
diff --git a/src/main/java/net/minecraft/client/render/shader/ShadersRenderer.java b/src/main/java/net/minecraft/client/render/shader/ShadersRenderer.java
index b5c93cd47..38026b551 100644
--- a/src/main/java/net/minecraft/client/render/shader/ShadersRenderer.java
+++ b/src/main/java/net/minecraft/client/render/shader/ShadersRenderer.java
@@ -15,8 +15,10 @@ import net.minecraft.client.render.Renderer;
 import net.minecraft.client.render.Texture;
 import net.minecraft.core.Global;
 
-public class ShadersRenderer extends Renderer {
+public class ShadersRenderer implements Renderer {
 
+	public Minecraft mc;
+	
 	protected final Framebuffer worldFramebuffer = new Framebuffer();
 	protected final Texture worldFramebufferTex = new Texture();
 	protected final Texture worldFramebufferDepth = new Texture();
@@ -32,9 +34,12 @@ public class ShadersRenderer extends Renderer {
 	
 	public int fbWidth;
 	public int fbHeight;
+	
+	public int renderWidth;
+	public int renderHeight;
 
 	public ShadersRenderer(Minecraft minecraft) {
-		super(minecraft);
+		mc = minecraft;
 		
 		if(!Shaders.enableShaders) throw new RuntimeException("Shaders disabled!");
 	}
@@ -239,7 +244,18 @@ public class ShadersRenderer extends Renderer {
 			return internal;
 		}
 	}
+	
 	public Texture getWorldFramebufferTex(){
 		return worldFramebufferTex;
 	}
+	
+	@Override
+	public int getRenderWidth() {
+		return renderWidth;
+	}
+	
+	@Override
+	public int getRenderHeight() {
+		return renderHeight;
+	}
 }
diff --git a/src/main/java/net/minecraft/client/util/helper/ScreenshotHelper.java b/src/main/java/net/minecraft/client/util/helper/ScreenshotHelper.java
index d85e4f091..e3a18994c 100644
--- a/src/main/java/net/minecraft/client/util/helper/ScreenshotHelper.java
+++ b/src/main/java/net/minecraft/client/util/helper/ScreenshotHelper.java
@@ -11,6 +11,7 @@ import java.io.File;
 import javax.imageio.ImageIO;
 
 import net.minecraft.client.Minecraft;
+import net.minecraft.client.render.FallbackRenderer;
 import net.minecraft.client.render.Framebuffer;
 import net.minecraft.client.render.Renderer;
 import net.minecraft.client.render.Texture;
@@ -119,7 +120,7 @@ public class ScreenshotHelper {
 		fov = minecraft.gameSettings.FoV.value;
 		yaw = minecraft.thePlayer.yRot;
 		pitch = minecraft.thePlayer.xRot;
-		renderer = minecraft.render;
+		renderer = minecraft.renderer;
 		oldWidth = minecraft.resolution.width;
 		oldHeight = minecraft.resolution.height;
 		immersiveMode = minecraft.gameSettings.immersiveMode.value;
@@ -128,7 +129,7 @@ public class ScreenshotHelper {
 		minecraft.resolution.width = width;
 		minecraft.resolution.height = height;
 		
-		minecraft.render = new Renderer(minecraft);
+		minecraft.renderer = new FallbackRenderer(minecraft);
 	}
 	
 	public void delete() {
@@ -141,7 +142,7 @@ public class ScreenshotHelper {
 		minecraft.gameSettings.FoV.value = fov;
 		minecraft.thePlayer.yRot = yaw;
 		minecraft.thePlayer.xRot = pitch;
-		minecraft.render = renderer;
+		minecraft.renderer = renderer;
 		minecraft.resolution.width = oldWidth;
 		minecraft.resolution.height = oldHeight;
 		minecraft.gameSettings.immersiveMode.value = immersiveMode;
diff --git a/src/main/java/net/minecraft/client/world/WorldClient.java b/src/main/java/net/minecraft/client/world/WorldClient.java
index 78275056c..d79651dad 100644
--- a/src/main/java/net/minecraft/client/world/WorldClient.java
+++ b/src/main/java/net/minecraft/client/world/WorldClient.java
@@ -5,21 +5,18 @@ import java.util.LinkedList;
 import java.util.Set;
 
 import net.minecraft.client.Minecraft;
-import net.minecraft.core.world.Dimension;
-import net.minecraft.core.world.LevelListener;
-import net.minecraft.core.world.World;
-import net.minecraft.core.world.pathfinder.IdHashMap;
+import net.minecraft.client.net.handler.NetClientHandler;
+import net.minecraft.client.world.chunk.provider.ChunkProviderClient;
 import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.entity.Entity;
-import net.minecraft.client.net.handler.NetClientHandler;
 import net.minecraft.core.net.packet.Packet255KickDisconnect;
+import net.minecraft.core.world.Dimension;
+import net.minecraft.core.world.World;
 import net.minecraft.core.world.chunk.ChunkCoordinates;
 import net.minecraft.core.world.chunk.provider.IChunkProvider;
-import net.minecraft.client.world.chunk.provider.ChunkProviderClient;
+import net.minecraft.core.world.pathfinder.IdHashMap;
 import net.minecraft.core.world.save.SaveHandlerClientMP;
 
-import static net.minecraft.core.Global.DAY_LENGTH_TICKS;
-
 // Referenced classes of package net.minecraft.src:
 //            World, SaveHandlerMP, WorldProvider, MCHash, 
 //            ChunkCoordinates, NetClientHandler, IWorldAccess, Entity, 
@@ -45,17 +42,6 @@ public class WorldClient extends World
     @Override
 	public void tick()
     {
-        setWorldTime(getWorldTime() + 1L);
-        int i = worldType.getSkyDarken(this, getWorldTime(), 1.0F);
-        if(i != skyDarken)
-        {
-            skyDarken = i;
-            for(int j = 0; j < listeners.size(); j++)
-            {
-                listeners.get(j).allChanged();
-            }
-
-        }
         for(int k = 0; k < 10 && !field_1053_F.isEmpty(); k++)
         {
             Entity entity = (Entity)field_1053_F.iterator().next();
@@ -76,15 +62,7 @@ public class WorldClient extends World
                 field_1057_z.remove(l--);
             }
         }
-
-        // Todo fix issue where frozen daycycle at exactly day spams the renderer reload, client doesn't have a way of knowing if the daycycle is disabled or not currently
-        if (getWorldTime() % DAY_LENGTH_TICKS == 0)
-        {
-            for (LevelListener listener : listeners)
-            {
-                listener.allChanged();
-            }
-        }
+		updateSeasonAndLight();
     }
 
     public void processPackets() {
diff --git a/src/main/java/net/minecraft/core/net/command/commands/TimeCommand.java b/src/main/java/net/minecraft/core/net/command/commands/TimeCommand.java
index 1c9b318f6..340e8deb7 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/TimeCommand.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/TimeCommand.java
@@ -60,7 +60,7 @@ public class TimeCommand extends Command {
 
 			for (LevelListener listener : world.listeners)
 			{
-				listener.allChanged();
+				listener.allChanged(true, true);
 			}
 
 			return true;
@@ -73,7 +73,7 @@ public class TimeCommand extends Command {
 
 			for (LevelListener listener : world.listeners)
 			{
-				listener.allChanged();
+				listener.allChanged(true, true);
 			}
 
 			return true;
diff --git a/src/main/java/net/minecraft/core/world/LevelListener.java b/src/main/java/net/minecraft/core/world/LevelListener.java
index 6bb967ef3..0a509079a 100644
--- a/src/main/java/net/minecraft/core/world/LevelListener.java
+++ b/src/main/java/net/minecraft/core/world/LevelListener.java
@@ -36,7 +36,7 @@ public interface LevelListener
 
     void entityRemoved(Entity entity);
 
-    void allChanged();
+    void allChanged(boolean lightChanged, boolean seasonChanged);
 
     void playStreamingMusic(String soundPath, String Author, int x, int y, int z);
 
diff --git a/src/main/java/net/minecraft/core/world/World.java b/src/main/java/net/minecraft/core/world/World.java
index 56552794e..73f856909 100644
--- a/src/main/java/net/minecraft/core/world/World.java
+++ b/src/main/java/net/minecraft/core/world/World.java
@@ -1,8 +1,22 @@
 package net.minecraft.core.world;
 
+import static net.minecraft.core.Global.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+import java.util.TreeSet;
+
 import com.mojang.nbt.CompoundTag;
+
 import net.minecraft.client.render.LightmapHelper;
 import net.minecraft.client.render.camera.ICamera;
+import net.minecraft.client.render.colorizer.Colorizers;
 import net.minecraft.client.world.chunk.provider.ChunkProviderViewer;
 import net.minecraft.core.Global;
 import net.minecraft.core.HitResult;
@@ -54,19 +68,6 @@ import net.minecraft.core.world.type.WorldTypes;
 import net.minecraft.core.world.weather.Weather;
 import net.minecraft.core.world.weather.WeatherManager;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Random;
-import java.util.Set;
-import java.util.TreeSet;
-
-import static net.minecraft.core.Global.DAY_LENGTH_TICKS;
-import static net.minecraft.core.Global.accessor;
-
 public class World implements WorldSource {
 
     public static boolean AUTOSAVE = true;
@@ -89,7 +90,7 @@ public class World implements WorldSource {
     private final Set<NextTickListEntry> immediatelyUpdatedPositions = new HashSet<>();
     
     public boolean scheduledUpdatesAreImmediate = false;
-    private long dimensionColor = 0xffffffL;
+    private int dimensionColor = 0xffffff;
     public int skyDarken = 0;
     protected int updateLCG = new Random().nextInt();
     public int lightningFlicker = 0;
@@ -117,8 +118,8 @@ public class World implements WorldSource {
     public boolean isClientSide = false;
     public int sleepPercent = 100;
     private long runtime = 0;
-    public boolean updateAllOnLightChange = false;
-
+    public int dayCountLastTick;
+    
     private final BiomeProvider biomeProvider;
 
     public AuroraProvider auroraProvider;
@@ -1604,7 +1605,12 @@ public class World implements WorldSource {
         {
             blockTemperature = blockTemperature - (1.25f);
         }
-        int skyColor = getBiomeProvider().getBiome(x, y, z).getSkyColor(blockTemperature);
+        int skyColor;
+        if(Colorizers.sky.isEnabled()) {
+        	skyColor = Colorizers.sky.getColor(this, x, y, z);
+        }else {
+        	skyColor = getBiomeProvider().getBiome(x, y, z).getSkyColor(blockTemperature);	
+        }
         float r = (float)(skyColor >> 16 & 0xff) / 255F;
         float g = (float)(skyColor >> 8 & 0xff) / 255F;
         float b = (float)(skyColor & 0xff) / 255F;
@@ -1637,10 +1643,13 @@ public class World implements WorldSource {
 
     public float getCelestialAngle(float partialTick)
     {
+    	if(!getGameRule(GameRules.DO_DAY_CYCLE)) {
+    		partialTick = 1.0f;
+    	}
         return worldType.getCelestialAngle(this, levelData.getWorldTime(), partialTick);
     }
 
-    public Vec3d getDimensionColor(float partialTick)
+    public Vec3d getDimensionColor(ICamera camera, float partialTick)
     {
         float f1 = getCelestialAngle(partialTick);
         float f2 = MathHelper.cos(f1 * 3.141593F * 2.0F) * 2.0F + 0.5F;
@@ -1652,26 +1661,30 @@ public class World implements WorldSource {
         {
             f2 = 1.0F;
         }
-        float f3 = (float)(dimensionColor >> 16 & 255L) / 255F;
-        float f4 = (float)(dimensionColor >> 8 & 255L) / 255F;
-        float f5 = (float)(dimensionColor & 255L) / 255F;
+        int color = dimensionColor;
+        float r = (float)(color >> 16 & 255) / 255F;
+        float g = (float)(color >> 8 & 255) / 255F;
+        float b = (float)(color & 255) / 255F;
         float f6 = getCurrentWeather() != null && getCurrentWeather().isPrecipitation ? weatherManager.getWeatherIntensity() * weatherManager.getWeatherPower() : 0.0f;
         if(f6 > 0.0F)
         {
-            float f7 = (f3 * 0.3F + f4 * 0.59F + f5 * 0.11F) * 0.6F;
+            float f7 = (r * 0.3F + g * 0.59F + b * 0.11F) * 0.6F;
             float f9 = 1.0F - f6 * 0.95F;
-            f3 = f3 * f9 + f7 * (1.0F - f9);
-            f4 = f4 * f9 + f7 * (1.0F - f9);
-            f5 = f5 * f9 + f7 * (1.0F - f9);
+            r = r * f9 + f7 * (1.0F - f9);
+            g = g * f9 + f7 * (1.0F - f9);
+            b = b * f9 + f7 * (1.0F - f9);
         }
-        f3 *= f2 * 0.9F + 0.1F;
-        f4 *= f2 * 0.9F + 0.1F;
-        f5 *= f2 * 0.85F + 0.15F;
-        return Vec3d.createVector(f3, f4, f5);
+        r *= f2 * 0.9F + 0.1F;
+        g *= f2 * 0.9F + 0.1F;
+        b *= f2 * 0.85F + 0.15F;
+        return Vec3d.createVector(r, g, b);
     }
 
-    public Vec3d getFogColor(double x, double y, double z, float partialTick)
+    public Vec3d getFogColor(ICamera camera, float partialTick)
     {
+    	double x = camera.getX(partialTick);
+    	double y = camera.getY(partialTick);
+    	double z = camera.getZ(partialTick);
         float celestialAngle = getCelestialAngle(partialTick);
         return worldType.getFogColor(this, x, y, z, celestialAngle, partialTick);
     }
@@ -2466,31 +2479,10 @@ public class World implements WorldSource {
         spawnPeacefulMobs = flag1;
     }
 
-    public void doLightingUpdate()
-    {
-        int i = worldType.getSkyDarken(this, getWorldTime(), 1.0F);
-        if(i != skyDarken)
-        {
-            skyDarken = i;
-            if(updateAllOnLightChange) {
-                for(int j = 0; j < listeners.size(); j++)
-                {
-                    ((LevelListener) listeners.get(j)).allChanged();
-                }	
-            }
-        }
-    }
-
-    public void doSeasonUpdate(boolean forceUpdate)
-    {
-        // Todo replace with better fix for frozen time spamming render updates then just checking the day cycle
-        if (getWorldTime() % DAY_LENGTH_TICKS == 0 && getGameRule(GameRules.DO_DAY_CYCLE) || forceUpdate)
-        {
-            for(int j = 0; j < listeners.size(); j++)
-            {
-                listeners.get(j).allChanged();
-            }
-        }
+    public void allChanged(boolean lightChanged, boolean seasonChanged) {
+		for(int i= 0; i < listeners.size(); i++) {
+            listeners.get(i).allChanged(lightChanged, seasonChanged);
+		}
     }
 
     protected void updateSleepingPlayers()
@@ -2512,35 +2504,52 @@ public class World implements WorldSource {
         }
     }
 
-    public void tick()
-    {
-        immediatelyUpdatedPositions.clear();
-        weatherManager.tick();
-        updateSleepingPlayers();
-        SpawnerMobs.performSpawning(this, spawnHostileMobs, spawnPeacefulMobs);
-        chunkProvider.tick();
-        doLightingUpdate();
-        long l1 = levelData.getWorldTime() + 1L;
-        int autosaveTimeInSeconds = Global.accessor.getAutosaveTimer();
+	public void tick() {
+		immediatelyUpdatedPositions.clear();
+		weatherManager.tick();
+		updateSleepingPlayers();
+		SpawnerMobs.performSpawning(this, spawnHostileMobs, spawnPeacefulMobs);
+		chunkProvider.tick();
 
-        int autosaveTimeInTicks = (autosaveTimeInSeconds * 20);
+		int autosaveTimeInSeconds = Global.accessor.getAutosaveTimer();
+		int autosaveTimeInTicks = (autosaveTimeInSeconds * 20);
 
-        AUTOSAVE = autosaveTimeInTicks != 0;
+		AUTOSAVE = autosaveTimeInTicks != 0;
+		if(AUTOSAVE && runtime % (long) autosaveTimeInTicks == 0L) {
+			saveWorld(false, null, true);
+		}
 
-        if (AUTOSAVE && runtime % (long)autosaveTimeInTicks == 0L)
-        {
-            saveWorld(false, null, true);
-        }
+		if(getGameRule(GameRules.DO_DAY_CYCLE)) {
+			levelData.setWorldTime(levelData.getWorldTime() + 1L);
+		}
 
-        if (getGameRule(GameRules.DO_DAY_CYCLE)){
-            levelData.setWorldTime(l1);
-        }
-        runtime++;
-        tickUpdates(false);
-        updateBlocksAndPlayCaveSounds();
+		runtime++;
 
-        doSeasonUpdate(false);
-    }
+		tickUpdates(false);
+		updateBlocksAndPlayCaveSounds();
+		updateSeasonAndLight();
+	}
+	
+	public void updateSeasonAndLight() {
+		boolean seasonChanged = false;
+		boolean lightChanged = false;
+
+		int currentDayCount = ((int) (levelData.getWorldTime() / Global.DAY_LENGTH_TICKS));
+		if(currentDayCount != dayCountLastTick) {
+			dayCountLastTick = currentDayCount;
+			seasonChanged = true;
+		}
+
+		int currentSkyDarken = worldType.getSkyDarken(this, getWorldTime(), 1.0f);
+		if(currentSkyDarken != skyDarken) {
+			skyDarken = currentSkyDarken;
+			lightChanged = true;
+		}
+
+		if(seasonChanged || lightChanged) {
+			allChanged(lightChanged, seasonChanged);
+		}
+	}
 
     protected void updateBlocksAndPlayCaveSounds()
     {
diff --git a/src/main/java/net/minecraft/core/world/biome/BiomeDryForest.java b/src/main/java/net/minecraft/core/world/biome/BiomeDryForest.java
deleted file mode 100644
index ecf762fb2..000000000
--- a/src/main/java/net/minecraft/core/world/biome/BiomeDryForest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package net.minecraft.core.world.biome;
-
-import net.minecraft.core.entity.animal.EntityWolf;
-import net.minecraft.core.block.Block;
-import net.minecraft.core.entity.SpawnListEntry;
-import net.minecraft.core.world.generate.feature.tree.*;
-import net.minecraft.core.world.generate.feature.WorldFeature;
-
-import java.util.Random;
-
-public class BiomeDryForest extends BiomeForest
-{
-
-    public BiomeDryForest(String key)
-    {
-        super(key);
-    }
-    @Override
-    public WorldFeature getRandomWorldGenForTrees(Random random)
-    {
-
-
-        if(random.nextInt(3) == 0)
-        {
-            return new WorldFeatureTreeShrub(Block.leavesShrub.id, Block.logOak.id);
-        } else
-        {
-            return new WorldFeatureTree(Block.leavesOak.id, Block.logOak.id, 4);
-        }
-    }
-}
diff --git a/src/main/java/net/minecraft/core/world/biome/Biomes.java b/src/main/java/net/minecraft/core/world/biome/Biomes.java
index a33780a53..6df483bca 100644
--- a/src/main/java/net/minecraft/core/world/biome/Biomes.java
+++ b/src/main/java/net/minecraft/core/world/biome/Biomes.java
@@ -30,8 +30,6 @@ public class Biomes
     public static final Biome OVERWORLD_OUTBACK_GRASSY = register("minecraft:overworld.outback.grassy", new BiomeOutback("outback.grassy").setColor(0xf09037).setBlockedWeathers(Weather.overworldSnow).setTopBlock(Block.grassScorched.id).setFillerBlock(Block.dirtScorched.id));
     public static final Biome OVERWORLD_CAATINGA = register("minecraft:overworld.caatinga", new BiomeCaatinga("caatinga").setColor(0xdecda6).setTopBlock(Block.mudBaked.id).setFillerBlock(Block.mudBaked.id).setBlockedWeathers(Weather.overworldSnow));
     public static final Biome OVERWORLD_CAATINGA_PLAINS = register("minecraft:overworld.caatinga.plains", new Biome("caatinga.plains").setColor(0xa19477).setTopBlock(Block.mudBaked.id).setFillerBlock(Block.mudBaked.id).setBlockedWeathers(Weather.overworldSnow));
-    public static final Biome OVERWORLD_FOREST_DRY = register("minecraft:overworld.forest.dry", new BiomeForest("forest.dry").setColor(0x85c472));
-
     public static Biome register(String key, Biome biome)
     {
         Registries.BIOMES.register(key, biome);
diff --git a/src/main/java/net/minecraft/core/world/biome/provider/BiomeProviderOverworld.java b/src/main/java/net/minecraft/core/world/biome/provider/BiomeProviderOverworld.java
index af39067e0..a80c83e70 100644
--- a/src/main/java/net/minecraft/core/world/biome/provider/BiomeProviderOverworld.java
+++ b/src/main/java/net/minecraft/core/world/biome/provider/BiomeProviderOverworld.java
@@ -354,17 +354,13 @@ public final class BiomeProviderOverworld
                 new BiomeRange(0.3, 0.5, 0.0, 0.05, 0.0, 1.0, 0.0, 1.0)
         );
         brm.addRange(Biomes.OVERWORLD_BIRCH_FOREST,
-                new BiomeRange(0.5, 0.75, 0.2, 0.4, 0.0, 1.0, 0.0, 1.0)
+                new BiomeRange(0.5, 0.75, 0.3, 0.5, 0.0, 1.0, 0.0, 1.0)
         );
         brm.addRange(Biomes.OVERWORLD_SHRUBLAND,
-                new BiomeRange(0.5, 0.75, 0.05, 0.2, 0.0, 1.0, 0.0, 1.0)
+                new BiomeRange(0.5, 0.75, 0.05, 0.3, 0.0, 1.0, 0.0, 1.0)
         );
-        brm.addRange(Biomes.OVERWORLD_PLAINS,
-                new BiomeRange(0.75, 0.85, 0.1, 0.4, 0.0, 1.0, 0.0, 1.0)
-        );
-
         brm.addRange(Biomes.OVERWORLD_SEASONAL_FOREST,
-                new BiomeRange(0.5, 0.75, 0.4, 1.0, 0.0, 1.0, 0.0, 1.0)
+                new BiomeRange(0.5, 0.75, 0.5, 1.0, 0.0, 1.0, 0.0, 1.0)
         );
         brm.addRange(Biomes.OVERWORLD_SWAMPLAND,
                 new BiomeRange(0.75, 0.95, 0.85, 1.0, 0.0, 1.0, 0.0, 1.0)
diff --git a/src/main/java/net/minecraft/core/world/generate/chunk/perlin/overworld/ChunkDecoratorOverworld.java b/src/main/java/net/minecraft/core/world/generate/chunk/perlin/overworld/ChunkDecoratorOverworld.java
index c9de4489d..aa7f16875 100644
--- a/src/main/java/net/minecraft/core/world/generate/chunk/perlin/overworld/ChunkDecoratorOverworld.java
+++ b/src/main/java/net/minecraft/core/world/generate/chunk/perlin/overworld/ChunkDecoratorOverworld.java
@@ -235,8 +235,8 @@ public class ChunkDecoratorOverworld
         if (biome == Biomes.OVERWORLD_FOREST) {
             treeDensity += k4 + 5;
         }
-        if (biome == Biomes.OVERWORLD_FOREST_DRY) {
-            treeDensity += k4 + 1;
+        if (biome == Biomes.OVERWORLD_SHRUBLAND) {
+            treeDensity += k4 - 2;
         }
         if (biome == Biomes.OVERWORLD_BIRCH_FOREST) {
             treeDensity += k4 + 4;
@@ -321,6 +321,10 @@ public class ChunkDecoratorOverworld
         if (biome == Biomes.OVERWORLD_SHRUBLAND) {
             byteMeadow = 1;
         }
+        if (biome == Biomes.OVERWORLD_TAIGA) {
+            byteMeadow = 1;
+        }
+
         for (int l14 = 0; l14 < byteMeadow; l14++) {
             int blockId = Block.flowerPurple.id;
             if (rand.nextInt(12) == 0) {
@@ -361,12 +365,13 @@ public class ChunkDecoratorOverworld
         if (biome == Biomes.OVERWORLD_GRASSLANDS) {
             byteMarigold = 1;
         }
-        if (biome == Biomes.OVERWORLD_FOREST_DRY) {
-            byteMarigold = 1;
-        }
         if (biome == Biomes.OVERWORLD_PLAINS) {
             byteMarigold = 5;
         }
+
+        if (biome == Biomes.OVERWORLD_CAATINGA || biome == Biomes.OVERWORLD_CAATINGA_PLAINS) {
+            byteMarigold = 5;
+        }
         if (biome == Biomes.OVERWORLD_OUTBACK_GRASSY || biome == Biomes.OVERWORLD_OUTBACK) {
             byteMarigold = 3;
         }
@@ -416,9 +421,6 @@ public class ChunkDecoratorOverworld
         if (biome == Biomes.OVERWORLD_RAINFOREST) {
             byte1 = 10;
         }
-        if (biome == Biomes.OVERWORLD_DESERT) {
-            byte1 = 5;
-        }
         if (biome == Biomes.OVERWORLD_SEASONAL_FOREST) {
             byte1 = 2;
         }
@@ -428,8 +430,8 @@ public class ChunkDecoratorOverworld
         if (biome == Biomes.OVERWORLD_BOREAL_FOREST) {
             byte1 = 5;
         }
-        if (biome == Biomes.OVERWORLD_PLAINS) {
-            byte1 = 4;
+        if (biome == Biomes.OVERWORLD_GRASSLANDS) {
+            byte1 = 8;
         }
         if (biome == Biomes.OVERWORLD_CAATINGA) {
             byte1 = 2;
diff --git a/src/main/java/net/minecraft/core/world/season/Season.java b/src/main/java/net/minecraft/core/world/season/Season.java
index 7bac74345..a10430110 100644
--- a/src/main/java/net/minecraft/core/world/season/Season.java
+++ b/src/main/java/net/minecraft/core/world/season/Season.java
@@ -88,51 +88,4 @@ public abstract class Season
 		this.growFlowers = true;
 		return this;
 	}
-	
-	protected int getPeakGrassColorizer(int color)
-	{
-		return color;
-	}
-	
-	protected int getPeakFoliageColorizer(int color)
-	{
-		return color;
-	}
-	
-	public int modifyGrassColorizer(int color, Season otherSeason, float blendAmount)
-	{
-		int myColor = getPeakGrassColorizer(color);
-		int otherColor = otherSeason.getPeakGrassColorizer(color);
-		
-		return blendColors(myColor, otherColor, blendAmount);
-	}
-	
-	public int modifyFoliageColorizer(int color, Season otherSeason, float blendAmount)
-	{
-		int myColor = getPeakFoliageColorizer(color);
-		int otherColor = otherSeason.getPeakFoliageColorizer(color);
-		
-		return blendColors(myColor, otherColor, blendAmount);
-	}
-	
-	public static int blendColors(int colorA, int colorB, float blendAmount)
-	{
-		int rA = (colorA >> 16) & 0xFF;
-		int gA = (colorA >> 8) & 0xFF;
-		int bA = (colorA >> 0) & 0xFF;
-		
-		int rB = (colorB >> 16) & 0xFF;
-		int gB = (colorB >> 8) & 0xFF;
-		int bB = (colorB >> 0) & 0xFF;
-		
-		int dr = rB - rA;
-		int dg = gB - gA;
-		int db = bB - bA;
-		
-		int r = rA + (int)(dr * blendAmount);
-		int g = gA + (int)(dg * blendAmount);
-		int b = bA + (int)(db * blendAmount);
-		
-		return (r << 16) | (g << 8) | (b << 0);
-	}
 }
diff --git a/src/main/java/net/minecraft/core/world/season/SeasonColorProperties.java b/src/main/java/net/minecraft/core/world/season/SeasonColorProperties.java
deleted file mode 100644
index 106f62859..000000000
--- a/src/main/java/net/minecraft/core/world/season/SeasonColorProperties.java
+++ /dev/null
@@ -1,220 +0,0 @@
-package net.minecraft.core.world.season;
-
-import java.util.Properties;
-
-public class SeasonColorProperties
-{
-    enum ColorMethod
-    {
-        none,
-        modify,
-        desaturate
-    }
-
-    enum ValueMethod
-    {
-        flat,
-        mult,
-        add
-    }
-
-    public ColorMethod grassMethod;
-    public float grassR;
-    public ValueMethod grassRMethod;
-    public float grassG;
-    public ValueMethod grassGMethod;
-    public float grassB;
-    public ValueMethod grassBMethod;
-
-    public ColorMethod foliageMethod;
-    public float foliageR;
-    public ValueMethod foliageRMethod;
-    public float foliageG;
-    public ValueMethod foliageGMethod;
-    public float foliageB;
-    public ValueMethod foliageBMethod;
-
-    public SeasonColorProperties(String name, Properties prop)
-    {
-        String sGrassMethod = prop.getProperty("season." + name + ".grass.method", "none");
-        String sGrassR = prop.getProperty("season." + name + ".grass.r", "*1.0");
-        String sGrassG = prop.getProperty("season." + name + ".grass.g", "*1.0");
-        String sGrassB = prop.getProperty("season." + name + ".grass.b", "*1.0");
-
-        String sFoliageMethod = prop.getProperty("season." + name + ".foliage.method", "none");
-        String sFoliageR = prop.getProperty("season." + name + ".foliage.r", "*1.0");
-        String sFoliageG = prop.getProperty("season." + name + ".foliage.g", "*1.0");
-        String sFoliageB = prop.getProperty("season." + name + ".foliage.b", "*1.0");
-
-        switch (sGrassMethod)
-        {
-            case "modify":
-                grassMethod = ColorMethod.modify;
-                break;
-            case "desaturate":
-                grassMethod = ColorMethod.desaturate;
-                break;
-            default:
-                grassMethod = ColorMethod.none;
-        }
-
-        if (sGrassR.startsWith("*"))
-        {
-            grassRMethod = ValueMethod.mult;
-            sGrassR = sGrassR.substring(1);
-        }
-        else if (sGrassR.startsWith("+"))
-        {
-            grassRMethod = ValueMethod.add;
-            sGrassR = sGrassR.substring(1);
-        }
-        else
-        {
-            grassRMethod = ValueMethod.flat;
-        }
-        try
-        {
-            grassR = Float.parseFloat(sGrassR);
-        }
-        catch (NumberFormatException e)
-        {
-            grassRMethod = ValueMethod.mult;
-            grassR = 1.0f;
-        }
-
-        if (sGrassG.startsWith("*"))
-        {
-            grassGMethod = ValueMethod.mult;
-            sGrassG = sGrassG.substring(1);
-        }
-        else if (sGrassG.startsWith("+"))
-        {
-            grassGMethod = ValueMethod.add;
-            sGrassG = sGrassG.substring(1);
-        }
-        else
-        {
-            grassGMethod = ValueMethod.flat;
-        }
-        try
-        {
-            grassG = Float.parseFloat(sGrassG);
-        }
-        catch (NumberFormatException e)
-        {
-            grassGMethod = ValueMethod.mult;
-            grassG = 1.0f;
-        }
-
-        if (sGrassB.startsWith("*"))
-        {
-            grassBMethod = ValueMethod.mult;
-            sGrassB = sGrassB.substring(1);
-        }
-        else if (sGrassB.startsWith("+"))
-        {
-            grassBMethod = ValueMethod.add;
-            sGrassB = sGrassB.substring(1);
-        }
-        else
-        {
-            grassBMethod = ValueMethod.flat;
-        }
-        try
-        {
-            grassB = Float.parseFloat(sGrassB);
-        }
-        catch (NumberFormatException e)
-        {
-            grassBMethod = ValueMethod.mult;
-            grassB = 1.0f;
-        }
-
-        switch (sFoliageMethod)
-        {
-            case "modify":
-                foliageMethod = ColorMethod.modify;
-                break;
-            case "desaturate":
-                foliageMethod = ColorMethod.desaturate;
-                break;
-            default:
-                foliageMethod = ColorMethod.none;
-        }
-
-        if (sFoliageR.startsWith("*"))
-        {
-            foliageRMethod = ValueMethod.mult;
-            sFoliageR = sFoliageR.substring(1);
-        }
-        else if (sFoliageR.startsWith("+"))
-        {
-            foliageRMethod = ValueMethod.add;
-            sFoliageR = sFoliageR.substring(1);
-        }
-        else
-        {
-            foliageRMethod = ValueMethod.flat;
-        }
-        try
-        {
-            foliageR = Float.parseFloat(sFoliageR);
-        }
-        catch (NumberFormatException e)
-        {
-            foliageRMethod = ValueMethod.mult;
-            foliageR = 1.0f;
-        }
-
-        if (sFoliageG.startsWith("*"))
-        {
-            foliageGMethod = ValueMethod.mult;
-            sFoliageG = sFoliageG.substring(1);
-        }
-        else if (sFoliageG.startsWith("+"))
-        {
-            foliageGMethod = ValueMethod.add;
-            sFoliageG = sFoliageG.substring(1);
-        }
-        else
-        {
-            foliageGMethod = ValueMethod.flat;
-        }
-        try
-        {
-            foliageG = Float.parseFloat(sFoliageG);
-        }
-        catch (NumberFormatException e)
-        {
-            foliageGMethod = ValueMethod.mult;
-            foliageG = 1.0f;
-        }
-
-        if (sFoliageB.startsWith("*"))
-        {
-            foliageBMethod = ValueMethod.mult;
-            sFoliageB = sFoliageB.substring(1);
-        }
-        else if (sFoliageB.startsWith("+"))
-        {
-            foliageBMethod = ValueMethod.add;
-            sFoliageB = sFoliageB.substring(1);
-        }
-        else
-        {
-            foliageBMethod = ValueMethod.flat;
-        }
-        try
-        {
-            foliageB = Float.parseFloat(sFoliageB);
-        }
-        catch (NumberFormatException e)
-        {
-            foliageBMethod = ValueMethod.mult;
-            foliageB = 1.0f;
-        }
-
-    }
-
-
-}
diff --git a/src/main/java/net/minecraft/core/world/season/SeasonColorized.java b/src/main/java/net/minecraft/core/world/season/SeasonColorized.java
deleted file mode 100644
index 1b84fb8dc..000000000
--- a/src/main/java/net/minecraft/core/world/season/SeasonColorized.java
+++ /dev/null
@@ -1,204 +0,0 @@
-package net.minecraft.core.world.season;
-
-import net.minecraft.core.util.helper.MathHelper;
-
-public abstract class SeasonColorized extends Season
-{
-    SeasonColorProperties scp = null;
-
-    public SeasonColorized(String id, boolean hasFallingLeaves, boolean hasDeeperSnow)
-    {
-        super(id, hasFallingLeaves, hasDeeperSnow);
-    }
-
-    @Override
-	public int getPeakGrassColorizer(int color)
-    {
-        int r = (color >> 16) & 0xFF;
-        int g = (color >> 8) & 0xFF;
-        int b = color & 0xFF;
-
-        if (scp.grassMethod == SeasonColorProperties.ColorMethod.none)
-        {
-            return color;
-        }
-        else if (scp.grassMethod == SeasonColorProperties.ColorMethod.modify)
-        {
-
-            if (scp.grassRMethod == SeasonColorProperties.ValueMethod.flat)
-            {
-                r = (int) (scp.grassR * 255);
-            }
-            else if (scp.grassRMethod == SeasonColorProperties.ValueMethod.mult)
-            {
-                r *= scp.grassR;
-            }
-            else if (scp.grassRMethod == SeasonColorProperties.ValueMethod.add)
-            {
-                r += scp.grassR;
-            }
-
-            if (scp.grassGMethod == SeasonColorProperties.ValueMethod.flat)
-            {
-                g = (int) (scp.grassG * 255);
-            }
-            else if (scp.grassGMethod == SeasonColorProperties.ValueMethod.mult)
-            {
-                g *= scp.grassG;
-            }
-            else if (scp.grassGMethod == SeasonColorProperties.ValueMethod.add)
-            {
-                g += scp.grassG;
-            }
-
-            if (scp.grassBMethod == SeasonColorProperties.ValueMethod.flat)
-            {
-                b = (int) (scp.grassB * 255);
-            }
-            else if (scp.grassBMethod == SeasonColorProperties.ValueMethod.mult)
-            {
-                b *= scp.grassB;
-            }
-            else if (scp.grassBMethod == SeasonColorProperties.ValueMethod.add)
-            {
-                b += scp.grassB;
-            }
-        }
-        else if (scp.grassMethod == SeasonColorProperties.ColorMethod.desaturate)
-        {
-            int grey = (r + g + b) / 3;
-
-            int dr = r - grey;
-            int dg = g - grey;
-            int db = b - grey;
-
-            if (scp.grassRMethod == SeasonColorProperties.ValueMethod.mult)
-            {
-                r = grey + (int)(dr * scp.grassR);
-            }
-            else
-            {
-                r = grey;
-            }
-
-            if (scp.grassGMethod == SeasonColorProperties.ValueMethod.mult)
-            {
-                g = grey + (int)(dg * scp.grassG);
-            }
-            else
-            {
-                g = grey;
-            }
-
-            if (scp.grassBMethod == SeasonColorProperties.ValueMethod.mult)
-            {
-                b = grey + (int)(db * scp.grassB);
-            }
-            else
-            {
-                b = grey;
-            }
-        }
-
-        if (r < 0) r = 0;
-        if (r > 255) r = 255;
-        if (g < 0) g = 0;
-        if (g > 255) g = 255;
-        if (b < 0) b = 0;
-        if (b > 255) b = 255;
-
-        return ((r << 16) | (g << 8) | (b << 0));
-    }
-
-    @Override
-	public int getPeakFoliageColorizer(int color)
-    {
-        int r = (color >> 16) & 0xFF;
-        int g = (color >> 8) & 0xFF;
-        int b = (color >> 0) & 0xFF;
-
-        if (scp.foliageMethod == SeasonColorProperties.ColorMethod.none)
-        {
-            return color;
-        }
-        else if (scp.foliageMethod == SeasonColorProperties.ColorMethod.modify)
-        {
-            if (scp.foliageRMethod == SeasonColorProperties.ValueMethod.flat)
-            {
-                r = (int) (scp.foliageR * 255);
-            }
-            else if (scp.foliageRMethod == SeasonColorProperties.ValueMethod.mult)
-            {
-                r *= scp.foliageR;
-            }
-            else if (scp.foliageRMethod == SeasonColorProperties.ValueMethod.add)
-            {
-                r += scp.foliageR;
-            }
-
-            if (scp.foliageGMethod == SeasonColorProperties.ValueMethod.flat)
-            {
-                g = (int) (scp.foliageG * 255);
-            }
-            else if (scp.foliageGMethod == SeasonColorProperties.ValueMethod.mult)
-            {
-                g *= scp.foliageG;
-            }
-            else if (scp.foliageGMethod == SeasonColorProperties.ValueMethod.add)
-            {
-                g += scp.foliageG;
-            }
-
-            if (scp.foliageBMethod == SeasonColorProperties.ValueMethod.flat)
-            {
-                b = (int) (scp.foliageB * 255);
-            }
-            else if (scp.foliageBMethod == SeasonColorProperties.ValueMethod.mult)
-            {
-                b *= scp.foliageB;
-            }
-            else if (scp.foliageBMethod == SeasonColorProperties.ValueMethod.add)
-            {
-                b += scp.foliageB;
-            }
-        }
-        else if (scp.foliageMethod == SeasonColorProperties.ColorMethod.desaturate)
-        {
-            int grey = (r + g + b) / 3;
-
-            int dr = r - grey;
-            int dg = g - grey;
-            int db = b - grey;
-
-            if (scp.foliageRMethod == SeasonColorProperties.ValueMethod.mult)
-            {
-                r = grey + (int)(dr * scp.foliageR);
-            }
-            else
-            {
-                r = grey;
-            }
-
-            if (scp.foliageGMethod == SeasonColorProperties.ValueMethod.mult)
-            {
-                g = grey + (int)(dg * scp.foliageG);
-            }
-            else
-            {
-                g = grey;
-            }
-
-            if (scp.foliageBMethod == SeasonColorProperties.ValueMethod.mult)
-            {
-                b = grey + (int)(db * scp.foliageB);
-            }
-            else
-            {
-                b = grey;
-            }
-        }
-
-        return ((MathHelper.clamp(r, 0, 255) << 16) | (MathHelper.clamp(g, 0, 255) << 8) | (MathHelper.clamp(b, 0, 255) << 0));
-    }
-
-}
diff --git a/src/main/java/net/minecraft/core/world/season/SeasonFall.java b/src/main/java/net/minecraft/core/world/season/SeasonFall.java
index f7d39c706..75cf65d23 100644
--- a/src/main/java/net/minecraft/core/world/season/SeasonFall.java
+++ b/src/main/java/net/minecraft/core/world/season/SeasonFall.java
@@ -1,28 +1,8 @@
 package net.minecraft.core.world.season;
 
-import net.minecraft.client.render.colorizer.ColorProperties;
+public class SeasonFall extends Season {
 
-public class SeasonFall extends SeasonColorized
-{
-
-	public SeasonFall(String id)
-	{
-		super(id , true, false);
-	}
-
-	@Override
-	public int getPeakGrassColorizer(int color)
-	{
-		scp = ColorProperties.getSeasonColor("fall");
-
-		return super.getPeakGrassColorizer(color);
-	}
-	
-	@Override
-	public int getPeakFoliageColorizer(int color)
-	{
-		scp = ColorProperties.getSeasonColor("fall");
-
-		return super.getPeakFoliageColorizer(color);
+	public SeasonFall(String id) {
+		super(id, true, false);
 	}
 }
diff --git a/src/main/java/net/minecraft/core/world/season/SeasonOverworldHell.java b/src/main/java/net/minecraft/core/world/season/SeasonOverworldHell.java
index c79e1f40c..2fa8b1f94 100644
--- a/src/main/java/net/minecraft/core/world/season/SeasonOverworldHell.java
+++ b/src/main/java/net/minecraft/core/world/season/SeasonOverworldHell.java
@@ -1,21 +1,7 @@
 package net.minecraft.core.world.season;
 
-public class SeasonOverworldHell extends Season
-{
-	public SeasonOverworldHell(String id)
-	{
+public class SeasonOverworldHell extends Season {
+	public SeasonOverworldHell(String id) {
 		super(id);
 	}
-
-	@Override
-	public int getPeakGrassColorizer(int color)
-	{
-		return 0x7A6150;
-	}
-	
-	@Override
-	public int getPeakFoliageColorizer(int color)
-	{
-		return getPeakGrassColorizer(color);
-	}
 }
diff --git a/src/main/java/net/minecraft/core/world/season/SeasonParadiseGold.java b/src/main/java/net/minecraft/core/world/season/SeasonParadiseGold.java
index 32a33cd93..3bde361de 100644
--- a/src/main/java/net/minecraft/core/world/season/SeasonParadiseGold.java
+++ b/src/main/java/net/minecraft/core/world/season/SeasonParadiseGold.java
@@ -1,22 +1,7 @@
 package net.minecraft.core.world.season;
 
-public class SeasonParadiseGold extends SeasonColorized
-{
-
-	public SeasonParadiseGold(String id)
-	{
+public class SeasonParadiseGold extends Season {
+	public SeasonParadiseGold(String id) {
 		super(id, true, false);
 	}
-
-	@Override
-	public int getPeakGrassColorizer(int color)
-	{
-		return 0xFFFFAE00;
-	}
-	
-	@Override
-	public int getPeakFoliageColorizer(int color)
-	{
-		return 0xFFFFC700;
-	}
 }
diff --git a/src/main/java/net/minecraft/core/world/season/SeasonParadiseSilver.java b/src/main/java/net/minecraft/core/world/season/SeasonParadiseSilver.java
index cca5850ff..997ccd0f1 100644
--- a/src/main/java/net/minecraft/core/world/season/SeasonParadiseSilver.java
+++ b/src/main/java/net/minecraft/core/world/season/SeasonParadiseSilver.java
@@ -1,22 +1,7 @@
 package net.minecraft.core.world.season;
 
-public class SeasonParadiseSilver extends SeasonColorized
-{
-
-	public SeasonParadiseSilver(String id)
-	{
+public class SeasonParadiseSilver extends Season {
+	public SeasonParadiseSilver(String id) {
 		super(id, true, false);
 	}
-
-	@Override
-	public int getPeakGrassColorizer(int color)
-	{
-		return 0xFFDFDFFF;
-	}
-	
-	@Override
-	public int getPeakFoliageColorizer(int color)
-	{
-		return 0xFFDFDFFF;
-	}
 }
diff --git a/src/main/java/net/minecraft/core/world/season/SeasonSpring.java b/src/main/java/net/minecraft/core/world/season/SeasonSpring.java
index 9bcca800c..5317c65ed 100644
--- a/src/main/java/net/minecraft/core/world/season/SeasonSpring.java
+++ b/src/main/java/net/minecraft/core/world/season/SeasonSpring.java
@@ -1,28 +1,7 @@
 package net.minecraft.core.world.season;
 
-import net.minecraft.client.render.colorizer.ColorProperties;
-
-public class SeasonSpring extends SeasonColorized
-{
-
-	public SeasonSpring(String id)
-	{
+public class SeasonSpring extends Season {
+	public SeasonSpring(String id) {
 		super(id, false, false);
 	}
-
-	@Override
-	public int getPeakGrassColorizer(int color)
-	{
-		scp = ColorProperties.getSeasonColor("spring");
-
-		return super.getPeakGrassColorizer(color);
-	}
-
-	@Override
-	public int getPeakFoliageColorizer(int color)
-	{
-		scp = ColorProperties.getSeasonColor("spring");
-
-		return super.getPeakFoliageColorizer(color);
-	}
 }
diff --git a/src/main/java/net/minecraft/core/world/season/SeasonSummer.java b/src/main/java/net/minecraft/core/world/season/SeasonSummer.java
index 3f4d5f436..592c3bdf0 100644
--- a/src/main/java/net/minecraft/core/world/season/SeasonSummer.java
+++ b/src/main/java/net/minecraft/core/world/season/SeasonSummer.java
@@ -1,28 +1,7 @@
 package net.minecraft.core.world.season;
 
-import net.minecraft.client.render.colorizer.ColorProperties;
-
-public class SeasonSummer extends SeasonColorized
-{
-
-	public SeasonSummer(String id)
-	{
+public class SeasonSummer extends Season {
+	public SeasonSummer(String id) {
 		super(id, false, false);
 	}
-
-	@Override
-	public int getPeakGrassColorizer(int color)
-	{
-		scp = ColorProperties.getSeasonColor("summer");
-
-		return super.getPeakGrassColorizer(color);
-	}
-
-	@Override
-	public int getPeakFoliageColorizer(int color)
-	{
-		scp = ColorProperties.getSeasonColor("summer");
-
-		return super.getPeakFoliageColorizer(color);
-	}
 }
diff --git a/src/main/java/net/minecraft/core/world/season/SeasonWinter.java b/src/main/java/net/minecraft/core/world/season/SeasonWinter.java
index a54a48ffb..c7b960ec3 100644
--- a/src/main/java/net/minecraft/core/world/season/SeasonWinter.java
+++ b/src/main/java/net/minecraft/core/world/season/SeasonWinter.java
@@ -1,28 +1,7 @@
 package net.minecraft.core.world.season;
 
-import net.minecraft.client.render.colorizer.ColorProperties;
-
-public class SeasonWinter extends SeasonColorized
-{
-
-	public SeasonWinter(String id)
-	{
+public class SeasonWinter extends Season {
+	public SeasonWinter(String id) {
 		super(id, false, true);
 	}
-
-	@Override
-	public int getPeakGrassColorizer(int color)
-	{
-		scp = ColorProperties.getSeasonColor("winter");
-
-		return super.getPeakGrassColorizer(color);
-	}
-
-	@Override
-	public int getPeakFoliageColorizer(int color)
-	{
-		scp = ColorProperties.getSeasonColor("winter");
-
-		return super.getPeakFoliageColorizer(color);
-	}
 }
diff --git a/src/main/java/net/minecraft/core/world/season/Seasons.java b/src/main/java/net/minecraft/core/world/season/Seasons.java
index 3a2c3ac37..9d709c3eb 100644
--- a/src/main/java/net/minecraft/core/world/season/Seasons.java
+++ b/src/main/java/net/minecraft/core/world/season/Seasons.java
@@ -1,10 +1,12 @@
 package net.minecraft.core.world.season;
 
-import net.minecraft.core.world.weather.Weather;
-
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
+import net.minecraft.core.world.weather.Weather;
+
 public abstract class Seasons
 {
     private static final Map<String, Season> SEASONS_MAP = new HashMap<>();
@@ -34,4 +36,17 @@ public abstract class Seasons
 
         return season;
     }
+    
+    public static List<Season> getAllSeasons() {
+		List<String> seasonNames = new ArrayList<>(SEASONS_MAP.keySet());
+		seasonNames.sort(String.CASE_INSENSITIVE_ORDER);
+		
+		List<Season> seasons = new ArrayList<>();
+		
+		for(int i=0; i < seasonNames.size(); i++) {
+			seasons.add(getSeason(seasonNames.get(i)));
+		}
+		
+		return seasons;
+    }
 }
diff --git a/src/main/java/net/minecraft/core/world/type/WorldTypeOverworld.java b/src/main/java/net/minecraft/core/world/type/WorldTypeOverworld.java
index cd33c55da..bec4698d6 100644
--- a/src/main/java/net/minecraft/core/world/type/WorldTypeOverworld.java
+++ b/src/main/java/net/minecraft/core/world/type/WorldTypeOverworld.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.world.type;
 
+import net.minecraft.client.render.colorizer.Colorizers;
 import net.minecraft.core.Global;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.util.helper.MathHelper;
@@ -132,20 +133,27 @@ public abstract class WorldTypeOverworld
     public Vec3d getFogColor(World world, double x, double y, double z, float celestialAngle, float partialTick)
     {
         float dayProgress = MathHelper.cos(celestialAngle * MathHelper.PI * 2.0F) * 2.0F + 0.5F;
-        if(dayProgress < 0.0F)
-        {
-            dayProgress = 0.0F;
-        }
-        if(dayProgress > 1.0F)
-        {
-            dayProgress = 1.0F;
+        dayProgress = MathHelper.clamp(dayProgress, 0.0f, 1.0f);
+        float r, g, b;
+        
+        if(Colorizers.fog.isEnabled()) {
+        	int x1 = MathHelper.floor_double(x);
+        	int y1 = MathHelper.floor_double(y);
+        	int z1 = MathHelper.floor_double(z);
+        	
+        	int color = Colorizers.fog.getColor(world, x1, y1, z1);
+        	
+        	r = ((color >> 16) & 0xFF) / 255.0f;
+        	g = ((color >> 8) & 0xFF) / 255.0f;
+        	b = (color & 0xFF) / 255.0f;
+        }else {
+            r = 0.7529412f;
+            g = 0.8470588f;
+            b = 1.0f;
         }
-        float r = 0.7529412F;
-        float g = 0.8470588F;
-        float b = 1.0f;
-        r *= dayProgress * 0.94F + 0.06F;
-        g *= dayProgress * 0.94F + 0.06F;
-        b *= dayProgress * 0.91F + 0.09F;
+        r *= dayProgress * 0.94f + 0.06f;
+        g *= dayProgress * 0.94f + 0.06f;
+        b *= dayProgress * 0.91f + 0.09f;
         return Vec3d.createVector(r, g, b);
     }
 
diff --git a/src/main/java/net/minecraft/core/world/type/WorldTypeParadise.java b/src/main/java/net/minecraft/core/world/type/WorldTypeParadise.java
index 02892ea35..89d46b8f0 100644
--- a/src/main/java/net/minecraft/core/world/type/WorldTypeParadise.java
+++ b/src/main/java/net/minecraft/core/world/type/WorldTypeParadise.java
@@ -1,5 +1,6 @@
 package net.minecraft.core.world.type;
 
+import net.minecraft.client.render.colorizer.Colorizers;
 import net.minecraft.core.Global;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.util.helper.MathHelper;
@@ -149,23 +150,30 @@ public abstract class WorldTypeParadise
     @Override
     public Vec3d getFogColor(World world, double x, double y, double z, float celestialAngle, float partialTick)
     {
-        int i = 0x8080a0;
         float f2 = MathHelper.cos(celestialAngle * 3.141593F * 2.0F) * 2.0F + 0.5F;
-        if(f2 < 0.0F)
-        {
-            f2 = 0.0F;
-        }
-        if(f2 > 1.0F)
-        {
-            f2 = 1.0F;
+        f2 = MathHelper.clamp(f2, 0.0f, 1.0f);
+        float r, g, b;
+        
+        if(Colorizers.fog.isEnabled()) {
+        	int x1 = MathHelper.floor_double(x);
+        	int y1 = MathHelper.floor_double(y);
+        	int z1 = MathHelper.floor_double(z);
+        	
+        	int color = Colorizers.fog.getColor(world, x1, y1, z1);
+        	
+        	r = ((color >> 16) & 0xFF) / 255.0f;
+        	g = ((color >> 8) & 0xFF) / 255.0f;
+        	b = (color & 0xFF) / 255.0f;
+        }else {
+            int i = 0x8080a0;
+            r = (float)(i >> 16 & 0xff) / 255.0f;
+            g = (float)(i >> 8 & 0xff) / 255.0f;
+            b = (float)(i & 0xff) / 255.0f;
         }
-        float f3 = (float)(i >> 16 & 0xff) / 255F;
-        float f4 = (float)(i >> 8 & 0xff) / 255F;
-        float f5 = (float)(i & 0xff) / 255F;
-        f3 *= f2 * 0.94F + 0.06F;
-        f4 *= f2 * 0.94F + 0.06F;
-        f5 *= f2 * 0.91F + 0.09F;
-        return Vec3d.createVector(f3, f4, f5);
+        r *= f2 * 0.94F + 0.06F;
+        g *= f2 * 0.94F + 0.06F;
+        b *= f2 * 0.91F + 0.09F;
+        return Vec3d.createVector(r, g, b);
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/server/world/WorldManager.java b/src/main/java/net/minecraft/server/world/WorldManager.java
index eeada38d3..5cdcf0983 100644
--- a/src/main/java/net/minecraft/server/world/WorldManager.java
+++ b/src/main/java/net/minecraft/server/world/WorldManager.java
@@ -98,7 +98,7 @@ public class WorldManager
     }
 
     @Override
-	public void allChanged()
+	public void allChanged(boolean lightChanged, boolean seasonChanged)
     {
     }
 
diff --git a/src/main/resources/assets/minecraft/textures/block/log_thorn_top.png b/src/main/resources/assets/minecraft/textures/block/log_thorn_top.png
index b17abcfca..1d9ecec20 100644
Binary files a/src/main/resources/assets/minecraft/textures/block/log_thorn_top.png and b/src/main/resources/assets/minecraft/textures/block/log_thorn_top.png differ
diff --git a/src/main/resources/assets/minecraft/textures/colormap/birch/default.png b/src/main/resources/assets/minecraft/textures/colormap/birch/default.png
new file mode 100644
index 000000000..cd1f2c032
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/colormap/birch/default.png differ
diff --git a/src/main/resources/assets/minecraft/textures/colormap/birch/overworld_fall.png b/src/main/resources/assets/minecraft/textures/colormap/birch/overworld_fall.png
new file mode 100644
index 000000000..581d04199
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/colormap/birch/overworld_fall.png differ
diff --git a/src/main/resources/assets/minecraft/textures/colormap/birch/overworld_winter.png b/src/main/resources/assets/minecraft/textures/colormap/birch/overworld_winter.png
new file mode 100644
index 000000000..0aa8d7bd6
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/colormap/birch/overworld_winter.png differ
diff --git a/src/main/resources/assets/minecraft/textures/colormap/cacao/default.png b/src/main/resources/assets/minecraft/textures/colormap/cacao/default.png
new file mode 100644
index 000000000..3f466f0b1
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/colormap/cacao/default.png differ
diff --git a/src/main/resources/assets/minecraft/textures/colormap/cherry/default.png b/src/main/resources/assets/minecraft/textures/colormap/cherry/default.png
new file mode 100644
index 000000000..29dfe1cc3
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/colormap/cherry/default.png differ
diff --git a/src/main/resources/assets/minecraft/textures/colormap/cherry/overworld_fall.png b/src/main/resources/assets/minecraft/textures/colormap/cherry/overworld_fall.png
new file mode 100644
index 000000000..4237b1f0d
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/colormap/cherry/overworld_fall.png differ
diff --git a/src/main/resources/assets/minecraft/textures/colormap/cherry/overworld_summer.png b/src/main/resources/assets/minecraft/textures/colormap/cherry/overworld_summer.png
new file mode 100644
index 000000000..3f466f0b1
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/colormap/cherry/overworld_summer.png differ
diff --git a/src/main/resources/assets/minecraft/textures/colormap/cherry/overworld_winter.png b/src/main/resources/assets/minecraft/textures/colormap/cherry/overworld_winter.png
new file mode 100644
index 000000000..0aa8d7bd6
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/colormap/cherry/overworld_winter.png differ
diff --git a/src/main/resources/assets/minecraft/textures/colormap/eucalyptus/default.png b/src/main/resources/assets/minecraft/textures/colormap/eucalyptus/default.png
new file mode 100644
index 000000000..c722fb89d
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/colormap/eucalyptus/default.png differ
diff --git a/src/main/resources/misc/grasscolor.png b/src/main/resources/assets/minecraft/textures/colormap/grass/default.png
similarity index 100%
rename from src/main/resources/misc/grasscolor.png
rename to src/main/resources/assets/minecraft/textures/colormap/grass/default.png
diff --git a/src/main/resources/misc/grasscolor_fall.png b/src/main/resources/assets/minecraft/textures/colormap/grass/overworld_fall.png
similarity index 100%
rename from src/main/resources/misc/grasscolor_fall.png
rename to src/main/resources/assets/minecraft/textures/colormap/grass/overworld_fall.png
diff --git a/src/main/resources/misc/grasscolor_spring.png b/src/main/resources/assets/minecraft/textures/colormap/grass/overworld_spring.png
similarity index 100%
rename from src/main/resources/misc/grasscolor_spring.png
rename to src/main/resources/assets/minecraft/textures/colormap/grass/overworld_spring.png
diff --git a/src/main/resources/misc/grasscolor_winter.png b/src/main/resources/assets/minecraft/textures/colormap/grass/overworld_winter.png
similarity index 100%
rename from src/main/resources/misc/grasscolor_winter.png
rename to src/main/resources/assets/minecraft/textures/colormap/grass/overworld_winter.png
diff --git a/src/main/resources/misc/foliagecolor.png b/src/main/resources/assets/minecraft/textures/colormap/oak/default.png
similarity index 100%
rename from src/main/resources/misc/foliagecolor.png
rename to src/main/resources/assets/minecraft/textures/colormap/oak/default.png
diff --git a/src/main/resources/assets/minecraft/textures/colormap/oak/overworld_fall.png b/src/main/resources/assets/minecraft/textures/colormap/oak/overworld_fall.png
new file mode 100644
index 000000000..9a8c224ae
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/colormap/oak/overworld_fall.png differ
diff --git a/src/main/resources/assets/minecraft/textures/colormap/palm/default.png b/src/main/resources/assets/minecraft/textures/colormap/palm/default.png
new file mode 100644
index 000000000..8e08a20cc
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/colormap/palm/default.png differ
diff --git a/src/main/resources/assets/minecraft/textures/colormap/pine/default.png b/src/main/resources/assets/minecraft/textures/colormap/pine/default.png
new file mode 100644
index 000000000..941b2b55c
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/colormap/pine/default.png differ
diff --git a/src/main/resources/assets/minecraft/textures/colormap/shrub/default.png b/src/main/resources/assets/minecraft/textures/colormap/shrub/default.png
new file mode 100644
index 000000000..b767adef4
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/colormap/shrub/default.png differ
diff --git a/src/main/resources/assets/minecraft/textures/colormap/shrub/overworld_fall.png b/src/main/resources/assets/minecraft/textures/colormap/shrub/overworld_fall.png
new file mode 100644
index 000000000..581d04199
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/colormap/shrub/overworld_fall.png differ
diff --git a/src/main/resources/assets/minecraft/textures/colormap/shrub/overworld_winter.png b/src/main/resources/assets/minecraft/textures/colormap/shrub/overworld_winter.png
new file mode 100644
index 000000000..0aa8d7bd6
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/colormap/shrub/overworld_winter.png differ
diff --git a/src/main/resources/assets/minecraft/textures/colormap/thorn/default.png b/src/main/resources/assets/minecraft/textures/colormap/thorn/default.png
new file mode 100644
index 000000000..58237a11c
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/colormap/thorn/default.png differ
diff --git a/src/main/resources/assets/minecraft/textures/colormap/thorn/overworld_spring.png b/src/main/resources/assets/minecraft/textures/colormap/thorn/overworld_spring.png
new file mode 100644
index 000000000..dc4dc6988
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/colormap/thorn/overworld_spring.png differ
diff --git a/src/main/resources/assets/minecraft/textures/colormap/thorn/overworld_winter.png b/src/main/resources/assets/minecraft/textures/colormap/thorn/overworld_winter.png
new file mode 100644
index 000000000..dc4dc6988
Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/colormap/thorn/overworld_winter.png differ
diff --git a/src/main/resources/misc/watercolor.png b/src/main/resources/assets/minecraft/textures/colormap/water/default.png
similarity index 100%
rename from src/main/resources/misc/watercolor.png
rename to src/main/resources/assets/minecraft/textures/colormap/water/default.png
diff --git a/src/main/resources/misc/colors.properties b/src/main/resources/misc/colors.properties
deleted file mode 100644
index 7fc051fc4..000000000
--- a/src/main/resources/misc/colors.properties
+++ /dev/null
@@ -1,126 +0,0 @@
-season.spring.grass.method=desaturate
-#season.spring.grass.r=*1.0
-season.spring.grass.r=*1.5
-season.spring.grass.g=*1.5
-season.spring.grass.b=*1.0
-#season.spring.grass.b=*1.0
-season.spring.foliage.method=desaturate
-#season.spring.foliage.r=*1.0
-season.spring.foliage.r=*1.5
-season.spring.foliage.g=*1.5
-#season.spring.foliage.b=*1.0
-#season.spring.foliage.b=*1.0
-
-#season.summer.grass.method=modify
-#season.summer.grass.r=*1.0
-#season.summer.grass.g=*1.0
-#season.summer.grass.b=*1.0
-#season.summer.grass.method=modify
-#season.summer.foliage.r=*1.0
-#season.summer.foliage.g=*1.0
-#season.summer.foliage.b=*1.0
-
-season.fall.grass.method=modify
-season.fall.grass.r=0.95
-season.fall.grass.g=0.85
-#season.fall.grass.b=*1.0
-season.fall.foliage.method=modify
-season.fall.foliage.r=0.941
-season.fall.foliage.g=*0.5
-season.fall.foliage.b=*0.3
-
-season.winter.grass.method=desaturate
-season.winter.grass.r=*0.95
-season.winter.grass.g=*0.95
-season.winter.grass.b=*0.95
-season.winter.foliage.method=desaturate
-season.winter.foliage.r=*0.9
-season.winter.foliage.g=*0.8
-season.winter.foliage.b=*0.8
-
-override.leaves.oak.inventory.r=0.282
-override.leaves.oak.inventory.g=0.71
-override.leaves.oak.inventory.b=0.094
-override.leaves.oak.winter.r=0.952
-override.leaves.oak.winter.g=0.785
-override.leaves.oak.winter.b=0.644
-
-override.leaves.birch.spring.r=0.502
-override.leaves.birch.spring.g=0.655
-override.leaves.birch.spring.b=0.333
-override.leaves.birch.summer.r=0.502
-override.leaves.birch.summer.g=0.655
-override.leaves.birch.summer.b=0.333
-override.leaves.birch.fall.r=1.0
-override.leaves.birch.fall.g=0.78
-override.leaves.birch.fall.b=0.18
-override.leaves.birch.winter.r=0.561
-override.leaves.birch.winter.g=0.514
-override.leaves.birch.winter.b=0.369
-
-override.leaves.pine.all.r=0.38
-override.leaves.pine.all.g=0.6
-override.leaves.pine.all.b=0.38
-
-override.leaves.eucalyptus.all.r=0.576
-override.leaves.eucalyptus.all.g=0.749
-override.leaves.eucalyptus.all.b=0.286
-
-override.leaves.cherry.inventory.r=1.0
-override.leaves.cherry.inventory.g=0.8
-override.leaves.cherry.inventory.b=0.925
-override.leaves.cherry.spring.r=1.0
-override.leaves.cherry.spring.g=0.8
-override.leaves.cherry.spring.b=0.925
-override.leaves.cherry.summer.r=0.29
-override.leaves.cherry.summer.g=0.659
-override.leaves.cherry.summer.b=0.125
-override.leaves.cherry.fall.r=0.82
-override.leaves.cherry.fall.g=0.192
-override.leaves.cherry.fall.b=0.122
-override.leaves.cherry.winter.r=0.561
-override.leaves.cherry.winter.g=0.514
-override.leaves.cherry.winter.b=0.369
-
-override.leaves.shrub.spring.r=0.502
-override.leaves.shrub.spring.g=0.655
-override.leaves.shrub.spring.b=0.333
-override.leaves.shrub.summer.r=0.502
-override.leaves.shrub.summer.g=0.655
-override.leaves.shrub.summer.b=0.333
-override.leaves.shrub.fall.r=1.0
-override.leaves.shrub.fall.g=0.78
-override.leaves.shrub.fall.b=0.18
-override.leaves.shrub.winter.r=0.561
-override.leaves.shrub.winter.g=0.514
-override.leaves.shrub.winter.b=0.369
-
-override.leaves.caatinga.spring.r=0.343
-override.leaves.caatinga.spring.g=0.679
-override.leaves.caatinga.spring.b=0.203
-override.leaves.caatinga.summer.r=0.714
-override.leaves.caatinga.summer.g=0.718
-override.leaves.caatinga.summer.b=0.339
-override.leaves.caatinga.fall.r=0.714
-override.leaves.caatinga.fall.g=0.718
-override.leaves.caatinga.fall.b=0.339
-override.leaves.caatinga.winter.r=0.343
-override.leaves.caatinga.winter.g=0.679
-override.leaves.caatinga.winter.b=0.203
-
-override.leaves.cocoa.all.r=0.29
-override.leaves.cocoa.all.g=0.659
-override.leaves.cocoa.all.b=0.125
-
-override.leaves.palm.spring.r=0.70
-override.leaves.palm.spring.g=0.90
-override.leaves.palm.spring.b=0.26
-override.leaves.palm.summer.r=0.70
-override.leaves.palm.summer.g=0.90
-override.leaves.palm.summer.b=0.26
-override.leaves.palm.fall.r=0.70
-override.leaves.palm.fall.g=0.90
-override.leaves.palm.fall.b=0.26
-override.leaves.palm.winter.r=0.70
-override.leaves.palm.winter.g=0.90
-override.leaves.palm.winter.b=0.26
