diff --git a/.gitignore b/.gitignore
index e4ac6288a..c530dabd6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,5 @@ logs/
 build.number
 run
 .vscode
+/.idea/
+/libs/
diff --git a/src/main/java/fi/dy/masa/tweakeroo/InitHandler.java b/src/main/java/fi/dy/masa/tweakeroo/InitHandler.java
index 4be534802..0d902bfdc 100644
--- a/src/main/java/fi/dy/masa/tweakeroo/InitHandler.java
+++ b/src/main/java/fi/dy/masa/tweakeroo/InitHandler.java
@@ -8,6 +8,7 @@
 import fi.dy.masa.malilib.event.WorldLoadHandler;
 import fi.dy.masa.malilib.interfaces.IInitializationHandler;
 import fi.dy.masa.malilib.interfaces.IRenderer;
+import fi.dy.masa.malilib.interfaces.IWorldLoadListener;
 import fi.dy.masa.tweakeroo.config.Callbacks;
 import fi.dy.masa.tweakeroo.config.Configs;
 import fi.dy.masa.tweakeroo.event.ClientTickHandler;
@@ -32,7 +33,10 @@ public void registerModHandlers()
         RenderEventHandler.getInstance().registerWorldLastRenderer(renderer);
 
         TickHandler.getInstance().registerClientTickHandler(new ClientTickHandler());
-        WorldLoadHandler.getInstance().registerWorldLoadPreHandler(new WorldLoadListener());
+
+        IWorldLoadListener worldListener = new WorldLoadListener();
+        WorldLoadHandler.getInstance().registerWorldLoadPreHandler(worldListener);
+        WorldLoadHandler.getInstance().registerWorldLoadPostHandler(worldListener);
 
         Callbacks.init(MinecraftClient.getInstance());
     }
diff --git a/src/main/java/fi/dy/masa/tweakeroo/event/WorldLoadListener.java b/src/main/java/fi/dy/masa/tweakeroo/event/WorldLoadListener.java
index 2a4a0be89..e84c24f70 100644
--- a/src/main/java/fi/dy/masa/tweakeroo/event/WorldLoadListener.java
+++ b/src/main/java/fi/dy/masa/tweakeroo/event/WorldLoadListener.java
@@ -14,4 +14,17 @@ public void onWorldLoadPre(@Nullable ClientWorld worldBefore, @Nullable ClientWo
         // Always disable the Free Camera mode when leaving the world or switching dimensions
         FeatureToggle.TWEAK_FREE_CAMERA.setBooleanValue(false);
     }
-}
+
+    @Override
+    public void onWorldLoadPost(@Nullable ClientWorld worldBefore, @Nullable ClientWorld worldAfter, MinecraftClient mc)
+    {
+        if (worldBefore == null)
+        {
+            if (FeatureToggle.TWEAK_GAMMA_OVERRIDE.getBooleanValue())
+            {
+                FeatureToggle.TWEAK_GAMMA_OVERRIDE.setBooleanValue(false);
+                FeatureToggle.TWEAK_GAMMA_OVERRIDE.setBooleanValue(true);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinExplosion.java b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinExplosion.java
index 09549c1ae..dd59a282f 100644
--- a/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinExplosion.java
+++ b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinExplosion.java
@@ -2,9 +2,8 @@
 
 import org.spongepowered.asm.mixin.Mixin;
 import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Redirect;
-import org.spongepowered.asm.mixin.injection.Slice;
-import net.minecraft.particle.DefaultParticleType;
+import org.spongepowered.asm.mixin.injection.ModifyArg;
+import net.minecraft.particle.ParticleEffect;
 import net.minecraft.particle.ParticleTypes;
 import net.minecraft.world.explosion.Explosion;
 import fi.dy.masa.tweakeroo.config.FeatureToggle;
@@ -12,14 +11,10 @@
 @Mixin(Explosion.class)
 public abstract class MixinExplosion
 {
-    @Redirect(method = "affectWorld",
-              slice = @Slice(
-                            from = @At("HEAD"),
-                            to = @At(value = "FIELD",
-                                     target = "Lnet/minecraft/world/explosion/Explosion;affectedBlocks:Lit/unimi/dsi/fastutil/objects/ObjectArrayList;")),
-              at = @At(value = "FIELD",
-                       target = "Lnet/minecraft/particle/ParticleTypes;EXPLOSION_EMITTER:Lnet/minecraft/particle/DefaultParticleType;"))
-    private DefaultParticleType redirectSpawnParticles()
+    @ModifyArg(method = "affectWorld",
+               at = @At(value = "INVOKE",
+               target = "Lnet/minecraft/world/World;addParticle(Lnet/minecraft/particle/ParticleEffect;DDDDDD)V"))
+    private ParticleEffect addParticleModify(ParticleEffect parameters)
     {
         if (FeatureToggle.TWEAK_EXPLOSION_REDUCED_PARTICLES.getBooleanValue())
         {
diff --git a/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinGameRenderer.java b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinGameRenderer.java
index 43c3f0df0..55975fa30 100644
--- a/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinGameRenderer.java
+++ b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinGameRenderer.java
@@ -1,24 +1,24 @@
 package fi.dy.masa.tweakeroo.mixin;
 
 import java.util.function.Predicate;
-import org.spongepowered.asm.mixin.Final;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.At.Shift;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.ModifyArg;
-import org.spongepowered.asm.mixin.injection.Redirect;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
 
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.render.Camera;
+import net.minecraft.client.render.CameraSubmersionType;
 import net.minecraft.client.render.GameRenderer;
 import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.entity.Entity;
 import net.minecraft.entity.LivingEntity;
 import net.minecraft.entity.decoration.AbstractDecorationEntity;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.Unique;
+import org.spongepowered.asm.mixin.injection.*;
+import org.spongepowered.asm.mixin.injection.At.Shift;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
 
 import fi.dy.masa.tweakeroo.config.Callbacks;
 import fi.dy.masa.tweakeroo.config.Configs;
@@ -30,12 +30,11 @@
 @Mixin(value = GameRenderer.class, priority = 1001)
 public abstract class MixinGameRenderer
 {
-    @Shadow @Final MinecraftClient client;
-
     @Shadow protected abstract void bobView(MatrixStack matrices, float tickDelta);
+    @Shadow @Final MinecraftClient client;
 
-    private float realYaw;
-    private float realPitch;
+    @Unique private float realYaw;
+    @Unique private float realPitch;
 
     @Inject(method = "renderWorld", at = @At("HEAD"), cancellable = true)
     private void onRenderWorld(CallbackInfo ci)
@@ -48,7 +47,7 @@ private void onRenderWorld(CallbackInfo ci)
 
     @Redirect(method = "renderWorld", require = 0, at = @At(value = "INVOKE",
               target = "Lnet/minecraft/client/render/GameRenderer;bobView(Lnet/minecraft/client/util/math/MatrixStack;F)V"))
-    private void disableWorldViewBob(GameRenderer renderer, MatrixStack matrices, float tickDelta)
+    private void disableWorldViewBob(GameRenderer instance, MatrixStack matrices, float tickDelta)
     {
         if (Configs.Disable.DISABLE_WORLD_VIEW_BOB.getBooleanValue() == false)
         {
@@ -63,10 +62,36 @@ private void applyZoom(Camera camera, float partialTicks, boolean useFOVSetting,
         {
             cir.setReturnValue(Configs.Generic.ZOOM_FOV.getDoubleValue());
         }
-        else if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue())
+    }
+
+    @ModifyExpressionValue(method = "getFov", at = @At(value = "CONSTANT", args = "doubleValue=70.0"))
+    private double applyFreeCameraFov(double original)
+    {
+        if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue())
         {
-            cir.setReturnValue((double) this.client.options.getFov().getValue());
+            return ((double) this.client.options.getFov().getValue());
         }
+
+        return original;
+    }
+
+    @ModifyVariable(method = "getFov", at = @At(value = "LOAD", ordinal = 0), argsOnly = true)
+    private boolean freezeFovOnFreeCamera(boolean value)
+    {
+        return !FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue() && value;
+    }
+
+    @ModifyExpressionValue(
+            method = "getFov",  at = @At(value = "INVOKE",
+            target = "Lnet/minecraft/client/render/Camera;getSubmersionType()Lnet/minecraft/client/render/CameraSubmersionType;"))
+    private CameraSubmersionType ignoreSubmersionTypeOnFreeCamera(CameraSubmersionType original)
+    {
+        if (FeatureToggle.TWEAK_FREE_CAMERA.getBooleanValue())
+        {
+            return CameraSubmersionType.NONE;
+        }
+
+        return original;
     }
 
     @Redirect(method = "updateTargetedEntity", at = @At(value = "INVOKE",
diff --git a/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinSignBlockEntity.java b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinSignBlockEntity.java
index 82c7ff620..0a3c7adc1 100644
--- a/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinSignBlockEntity.java
+++ b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinSignBlockEntity.java
@@ -12,6 +12,7 @@
 import net.minecraft.block.entity.SignBlockEntity;
 import net.minecraft.block.entity.SignText;
 import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.screen.ingame.HangingSignEditScreen;
 import net.minecraft.client.gui.screen.ingame.SignEditScreen;
 import net.minecraft.nbt.NbtCompound;
 import net.minecraft.util.math.BlockPos;
@@ -40,9 +41,12 @@ private void restoreCopiedText(NbtCompound nbt, CallbackInfo ci)
         {
             MinecraftClient mc = MinecraftClient.getInstance();
 
-            if ((mc.currentScreen instanceof SignEditScreen) && ((IGuiEditSign) mc.currentScreen).getTile() == (Object) this)
+            if (mc.currentScreen instanceof SignEditScreen || mc.currentScreen instanceof HangingSignEditScreen)
             {
-                MiscUtils.applyPreviousTextToSign((SignBlockEntity) (Object) this, null, ((SignBlockEntity) (Object) this).isPlayerFacingFront(mc.player));
+                if (((IGuiEditSign) mc.currentScreen).getTile() == (Object) this)
+                {
+                    MiscUtils.applyPreviousTextToSign((SignBlockEntity) (Object) this, null, ((SignBlockEntity) (Object) this).isPlayerFacingFront(mc.player));
+                }
             }
         }
     }