diff --git a/VERSION b/VERSION
index fc4e8f2a212689de102f9df2cb20f584e919aaa7..11f40b65beb9096be51f73a286a33bfed4ee0f89 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.7.10R0.2.1B3 Beta 3! Updated the Update Checker and added Tooltips.
\ No newline at end of file
+1.7.10R0.2.1B4 Beta 4! Now with better environment checks!.
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index f19527f4ded61adfa68c64146317266c1c5d7f80..c216faaa06a3b35f84435e0d47ddf226a3398fa3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -30,7 +30,7 @@ else
     println "!! No build number set !!"
 }
 
-version = "1.7.10-0.2.1-B3" + "-" + project.buildnumber
+version = "1.7.10-0.2.1-B4" + "-" + project.buildnumber
 group= "com.advancedmods.amcore" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
 archivesBaseName = "AMCore"
 
diff --git a/src/main/java/com/advancedmods/amcore/AMCore.java b/src/main/java/com/advancedmods/amcore/AMCore.java
index 44ee427410f364cd355449677854fd51fcf67265..cf6c0e6a1f8b11dbbef3d50f88ba2b12b91327ae 100644
--- a/src/main/java/com/advancedmods/amcore/AMCore.java
+++ b/src/main/java/com/advancedmods/amcore/AMCore.java
@@ -4,7 +4,8 @@ import com.advancedmods.amcore.common.CommonPlayerTracker;
 import com.advancedmods.amcore.common.CommonProxy;
 import com.advancedmods.amcore.common.handler.ConfigurationHandler;
 import com.advancedmods.amcore.core.AMCoreProps;
-import com.advancedmods.amcore.core.environment.CheckEnv;
+import com.advancedmods.amcore.core.environment.EnviromentChecks;
+import com.advancedmods.amcore.core.environment.IMCHandler;
 import com.advancedmods.amcore.core.mod.BaseMod;
 import com.advancedmods.amcore.core.mod.updater.UpdateManager;
 import cpw.mods.fml.common.FMLCommonHandler;
@@ -13,6 +14,8 @@ import cpw.mods.fml.common.Mod.EventHandler;
 import cpw.mods.fml.common.Mod.Instance;
 import cpw.mods.fml.common.SidedProxy;
 import cpw.mods.fml.common.event.FMLInitializationEvent;
+import cpw.mods.fml.common.event.FMLInterModComms;
+import cpw.mods.fml.common.event.FMLLoadCompleteEvent;
 import cpw.mods.fml.common.event.FMLPostInitializationEvent;
 import cpw.mods.fml.common.event.FMLPreInitializationEvent;
 import org.apache.logging.log4j.LogManager;
@@ -33,6 +36,7 @@ public class AMCore extends BaseMod {
     @SidedProxy(clientSide = AMCoreProps.clientproxy, serverSide = AMCoreProps.commonproxy)
     public static CommonProxy proxy;
     public static Logger log = LogManager.getLogger("AMCore");
+    public static final String issueURL = "https://github.com/AdvancedMods/AMCore/issues";
     public static final String updateURL = "https://raw.github.com/AdvancedMods/AMCore/master/VERSION";
     public static final String downloadURL = "http://ci.zsinfo.nl/job/AMCore/lastSuccessfulBuild/";
     public static ConfigurationHandler config;
@@ -42,14 +46,49 @@ public class AMCore extends BaseMod {
 
         log.info("Starting AMCore version: " + AMCoreProps.version + "...");
         log.info("Entering Pre-Init...");
+        // MC Version check
         log.debug("Checking MC version...");
-        CheckEnv.checkMCVersion();
+        EnviromentChecks.checkMCVersion();
+        // Optifine check
+        try {
+            EnviromentChecks.log.info("Checking if optifine is installed...");
+            EnviromentChecks.checkOptifine();
+            EnviromentChecks.log.info("Check complete");
+        } catch (Exception e) {
+            EnviromentChecks.log.warn("=============================WARNING!=============================");
+            EnviromentChecks.log.warn("Failed to check for optifine, assuming not installed");
+            EnviromentChecks.log.warn("Bug reports may not be complete!");
+            EnviromentChecks.log.warn("Please report this as a bug report with the stacktrace, the minecraft log, a mod list + version and if you have optifine installed to: " + issueURL);
+            EnviromentChecks.log.warn("=============================WARNING!=============================");
+            e.printStackTrace();
+        }
+        // Obfuscation check
+        try {
+            EnviromentChecks.log.info("Checking if we are in a deobfuscated environment...");
+            EnviromentChecks.checkDeobf();
+            EnviromentChecks.log.info("Check complete");
+        } catch (Exception e) {
+            EnviromentChecks.log.error("=============================ERROR!=============================");
+            EnviromentChecks.log.error("Failed to check obfuscation, assuming we are in a normal enviroment.");
+            EnviromentChecks.log.error("This is a severe error and should be investigated ASAP!");
+            EnviromentChecks.log.error("Please report this as a bug report with the stacktrace, the minecraft log and a mod list + version to: " + issueURL);
+            EnviromentChecks.log.error("=============================ERROR!=============================");
+            e.printStackTrace();
+        }
         // Do PreInit stuff
         // Load the config
-        log.info("Loading config...");
-        ConfigurationHandler.init(event.getSuggestedConfigurationFile());
-        FMLCommonHandler.instance().bus().register(new ConfigurationHandler());
-        log.info("Config loaded");
+        try {
+            log.info("Loading config...");
+            ConfigurationHandler.init(event.getSuggestedConfigurationFile());
+            FMLCommonHandler.instance().bus().register(new ConfigurationHandler());
+            log.info("Config loaded");
+        } catch (Exception e) {
+            log.error("=============================ERROR!=============================");
+            log.error("Failed to load the config, printing stacktrace and using default values...");
+            log.error("Please report this as a bug report with the stacktrace, the minecraft log and a mod list + version to: " + issueURL);
+            log.error("=============================ERROR!=============================");
+            e.printStackTrace();
+        }
         // Loading mod stuff
         // Checking for updated version
         if (config.enableUpdateChecker) {
@@ -58,7 +97,10 @@ public class AMCore extends BaseMod {
                 UpdateManager.registerUpdater(new UpdateManager(this, updateURL, downloadURL));
                 log.info("Update Checker for AMCore started");
             } catch (Exception e) {
+                log.error("=============================ERROR!=============================");
                 log.error("Failed to start the update checker, printing stacktrace...");
+                log.error("Please report this as a bug report with the stacktrace, the minecraft log and a mod list + version to: " + issueURL);
+                log.error("=============================ERROR!=============================");
                 e.printStackTrace();
             }
         } else if (!config.enableUpdateChecker) {
@@ -68,14 +110,25 @@ public class AMCore extends BaseMod {
             try {
                 UpdateManager.registerUpdater(new UpdateManager(this, updateURL, downloadURL));
             } catch (Exception e) {
+                log.error("=============================ERROR!=============================");
                 log.error("Failed to start the update checker, printing stacktrace...");
+                log.error("Please report this as a bug report with the stacktrace, the minecraft log and a mod list + version to: " + issueURL);
+                log.error("=============================ERROR!=============================");
                 e.printStackTrace();
             }
         }
-        log.info("Registering trackers...");
-        FMLCommonHandler.instance().bus().register(new CommonPlayerTracker());
-        proxy.loadTracker();
-        log.info("Trackers Registered");
+        try {
+            log.info("Registering trackers...");
+            FMLCommonHandler.instance().bus().register(new CommonPlayerTracker());
+            proxy.loadTracker();
+            log.info("Trackers Registered");
+        } catch (Exception e) {
+            log.error("=============================ERROR!=============================");
+            log.error("Failed to register the trackers, printing stacktrace...");
+            log.error("Please report this as a bug report with the stacktrace, the minecraft log and a mod list + version to: " + issueURL);
+            log.error("=============================ERROR!=============================");
+            e.printStackTrace();
+        }
         log.info("Pre-Init Finished");
 
     }
@@ -99,6 +152,40 @@ public class AMCore extends BaseMod {
 
     }
 
+    @EventHandler
+    public void handleIMC(FMLInterModComms.IMCEvent event) {
+
+        // IMCHandler
+        try {
+            log.info("Processing IMC messages...");
+            IMCHandler.processIMC(event.getMessages());
+            log.info("IMC Messages processed.");
+        } catch (Exception e) {
+            log.error("=============================ERROR!=============================");
+            log.error("Failed to process IMC Messages, printing stacktrace...");
+            log.error("Please report this as a bug report with the stacktrace, the minecraft log and a mod list + version to: " + issueURL);
+            log.error("=============================ERROR!=============================");
+            e.printStackTrace();
+        }
+    }
+
+    @EventHandler
+    public void loadComplete(FMLLoadCompleteEvent event) {
+
+        // Fetching runtime messages
+        try {
+            log.info("Fetching runtime IMC messages...");
+            IMCHandler.processIMC(FMLInterModComms.fetchRuntimeMessages(this));
+            log.info("Fetched runtime IMC messages.");
+        } catch (Exception e) {
+            log.error("=============================ERROR!=============================");
+            log.error("Failed to fetch IMC Runtime messages, printing stacktrace...");
+            log.error("Please report this as a bug report with the stacktrace, the minecraft log and a mod list + version to: " + issueURL);
+            log.error("=============================ERROR!=============================");
+            e.printStackTrace();
+        }
+    }
+
     @Override
     public String getModId() {
         return AMCoreProps.modid;
diff --git a/src/main/java/com/advancedmods/amcore/core/AMCoreProps.java b/src/main/java/com/advancedmods/amcore/core/AMCoreProps.java
index 68ea85781bd799a312de27b8cac6b7b7fc64b8ec..b7e4cbabc378505da16c6e5630ec0deeb4a64338 100644
--- a/src/main/java/com/advancedmods/amcore/core/AMCoreProps.java
+++ b/src/main/java/com/advancedmods/amcore/core/AMCoreProps.java
@@ -14,7 +14,7 @@ public class AMCoreProps {
     public static final String REQUIRED_FORGE_BASE = "10.13.2.1240";
     public static final String FORGE_VERSION = "[" + REQUIRED_FORGE_BASE + "]";
     public static final String VERSION_BASE = "R0.2.1";
-    public static final String VERSION_IDENTIFIER = "B3";
+    public static final String VERSION_IDENTIFIER = "B4";
     public static final String VERSION_COMPLETE = MC_VERSION + VERSION_BASE + VERSION_IDENTIFIER;
 
     // General Mod Stuff
diff --git a/src/main/java/com/advancedmods/amcore/core/environment/CheckEnv.java b/src/main/java/com/advancedmods/amcore/core/environment/CheckEnv.java
deleted file mode 100644
index 1f8003ee2291a4ad7311c93f8f35d9e35056fa8b..0000000000000000000000000000000000000000
--- a/src/main/java/com/advancedmods/amcore/core/environment/CheckEnv.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.advancedmods.amcore.core.environment;
-
-import com.advancedmods.amcore.AMCore;
-import com.advancedmods.amcore.core.AMCoreProps;
-import cpw.mods.fml.common.FMLLog;
-import cpw.mods.fml.common.Loader;
-
-/**
- * Environment checker for AMCore
- * Created by Dennisbonke on 9-2-2015.
- *
- * @author Dennis Bonke
- * @since 0.2.0B1
- */
-public class CheckEnv {
-
-    public static void checkMCVersion() {
-
-        if (Loader.MC_VERSION == AMCoreProps.MC_VERSION) {
-            AMCore.log.trace("Using MC Version 1.7.10, proceed");
-        } else {
-            FMLLog.severe("Not using MC version 1.7.10, aborting");
-            System.gc();
-            System.exit(-1);
-        }
-    }
-}
diff --git a/src/main/java/com/advancedmods/amcore/core/environment/EnviromentChecks.java b/src/main/java/com/advancedmods/amcore/core/environment/EnviromentChecks.java
new file mode 100644
index 0000000000000000000000000000000000000000..9afb0972d807d82dda308b8d1005ae8e16c8c13d
--- /dev/null
+++ b/src/main/java/com/advancedmods/amcore/core/environment/EnviromentChecks.java
@@ -0,0 +1,76 @@
+package com.advancedmods.amcore.core.environment;
+
+import com.advancedmods.amcore.core.AMCoreProps;
+import cpw.mods.fml.client.FMLClientHandler;
+import cpw.mods.fml.common.FMLCommonHandler;
+import cpw.mods.fml.common.FMLLog;
+import cpw.mods.fml.common.Loader;
+import cpw.mods.fml.relauncher.Side;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+/**
+ * Environment checker for AMCore
+ * Created by Dennisbonke on 9-2-2015.
+ *
+ * @author Dennis Bonke
+ * @since 0.2.0B1
+ */
+public class EnviromentChecks {
+
+    public static boolean hasOptifine;
+    protected static boolean isDeobf;
+    public static Logger log = LogManager.getLogger("AM-Enviroment");
+    public static final String issueURL = "https://github.com/AdvancedMods/AMCore/issues";
+
+    public static void checkOptifine()
+    {
+        try {
+            if ((FMLCommonHandler.instance().getSidedDelegate().getSide() == Side.CLIENT) && ((FMLClientHandler.instance().hasOptifine()) || (Loader.isModLoaded("optifine")))) {
+                hasOptifine = true;
+                log.warn("Optifine has been detected on your Minecraft installation, this can cause (rendering) issues");
+            } else {
+                hasOptifine = false;
+            }
+        } catch (Exception e) {
+            log.warn("=============================WARNING!=============================");
+            log.warn("Failed to check for optifine, assuming not installed");
+            log.warn("Bug reports may not be complete!");
+            log.warn("Please report this as a bug report with the stacktrace, the minecraft log, a mod list + version and if you have optifine installed to: " + issueURL);
+            log.warn("=============================WARNING!=============================");
+            e.printStackTrace();
+            hasOptifine = false;
+        }
+    }
+
+    public static void checkDeobf() {
+
+        try {
+            if (ObfUtil.isObf() == true) {
+                isDeobf = true;
+            } else {
+                isDeobf = false;
+            }
+        } catch (Exception e) {
+            log.error("=============================ERROR!=============================");
+            log.error("Failed to check obfuscation, assuming we are in a normal enviroment.");
+            log.error("This is a severe error and should be investigated ASAP!");
+            log.error("Please report this as a bug report with the stacktrace, the minecraft log and a mod list + version to: " + issueURL);
+            log.error("=============================ERROR!=============================");
+            e.printStackTrace();
+            isDeobf = false;
+        }
+    }
+
+    public static void checkMCVersion() {
+
+        if (Loader.MC_VERSION == AMCoreProps.MC_VERSION) {
+            log.trace("Using MC Version 1.7.10, proceed");
+        } else {
+            FMLLog.log(Level.FATAL, "Not using MC version 1.7.10, aborting");
+            System.gc();
+            System.exit(-1);
+        }
+    }
+}
diff --git a/src/main/java/com/advancedmods/amcore/core/environment/IMCHandler.java b/src/main/java/com/advancedmods/amcore/core/environment/IMCHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..79f5aa75d0c9356755395762e38c7c5e6d8be045
--- /dev/null
+++ b/src/main/java/com/advancedmods/amcore/core/environment/IMCHandler.java
@@ -0,0 +1,21 @@
+package com.advancedmods.amcore.core.environment;
+
+import cpw.mods.fml.common.event.FMLInterModComms;
+
+import java.util.List;
+
+/**
+ * Created by Dennisbonke on 15-4-2015.
+ */
+public final class IMCHandler {
+
+    public static void processIMC(List<FMLInterModComms.IMCMessage> messages)
+    {
+        for (FMLInterModComms.IMCMessage message : messages)
+        {
+            String type = message.key;
+            if ((type == null) || (type.isEmpty())) {}
+        }
+    }
+
+}
diff --git a/src/main/java/com/advancedmods/amcore/core/environment/ObfUtil.java b/src/main/java/com/advancedmods/amcore/core/environment/ObfUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..e4ea03ac60c2783161ea4a2de7b10b0196998f7e
--- /dev/null
+++ b/src/main/java/com/advancedmods/amcore/core/environment/ObfUtil.java
@@ -0,0 +1,169 @@
+package com.advancedmods.amcore.core.environment;
+
+import cpw.mods.fml.relauncher.ReflectionHelper;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+/**
+ * Created by Dennisbonke on 15-4-2015.
+ */
+public class ObfUtil {
+
+    public static boolean isObf()
+    {
+        try
+        {
+            Field[] fields = Class.forName("net.minecraft.world.World").getDeclaredFields();
+            for (Field f : fields)
+            {
+                f.setAccessible(true);
+                if (f.getName().equalsIgnoreCase("loadedEntityList")) {
+                    return false;
+                }
+            }
+        }
+        catch (Exception e)
+        {
+            return true;
+        }
+        return true;
+    }
+
+    public static boolean isFieldAccessible(Class<?> clazz, String... names)
+    {
+        try
+        {
+            Field[] fields = clazz.getDeclaredFields();
+            for (Field field : fields) {
+                for (String fieldName : names) {
+                    if (field.getName().equalsIgnoreCase(fieldName)) {
+                        return field.isAccessible();
+                    }
+                }
+            }
+        }
+        catch (Exception e)
+        {
+            throw new ReflectionHelper.UnableToFindFieldException(names, e);
+        }
+        return false;
+    }
+
+    public static void setFieldAccessible(Class<?> clazz, String... names)
+    {
+        try
+        {
+            Field field = getField(clazz, names);
+            if (field != null) {
+                field.setAccessible(true);
+            }
+        }
+        catch (Exception e) {}
+    }
+
+    public static <T, E> void setFieldValue(Class<? extends E> clazz, E instance, Object value, String... names)
+    {
+        try
+        {
+            Field field = getField(clazz, names);
+            if (field != null) {
+                field.set(instance, value);
+            }
+        }
+        catch (Exception e) {}
+    }
+
+    public static <T, E> T getFieldValue(Class<? extends E> clazz, E instance, String... names)
+    {
+        try
+        {
+            return (T)getField(clazz, names).get(instance);
+        }
+        catch (Exception e)
+        {
+            throw new ReflectionHelper.UnableToAccessFieldException(names, e);
+        }
+    }
+
+    public static Field getField(Class<?> clazz, String... names)
+    {
+        try
+        {
+            Field[] fields = clazz.getDeclaredFields();
+            for (Field field : fields) {
+                for (String fieldName : names) {
+                    if (field.getName().equalsIgnoreCase(fieldName))
+                    {
+                        field.setAccessible(true);
+                        return field;
+                    }
+                }
+            }
+        }
+        catch (Exception e)
+        {
+            throw new ReflectionHelper.UnableToFindFieldException(names, e);
+        }
+        return null;
+    }
+
+    public static boolean isMethodAccessable(Class<?> clazz, String... names)
+    {
+        try
+        {
+            Method[] methods = clazz.getDeclaredMethods();
+            for (Method method : methods) {
+                for (String methodName : names) {
+                    if (method.getName().equalsIgnoreCase(methodName)) {
+                        return method.isAccessible();
+                    }
+                }
+            }
+        }
+        catch (Exception e)
+        {
+            throw new ReflectionHelper.UnableToFindMethodException(names, e);
+        }
+        return false;
+    }
+
+    public static <T, E> Object invokeMethod(Class<? extends E> clazz, E instance, String[] names, Object... args)
+    {
+        try
+        {
+            Method method = getMethod(clazz, names);
+            if (method != null) {
+                return method.invoke(instance, args);
+            }
+        }
+        catch (Exception e)
+        {
+            throw new ReflectionHelper.UnableToFindMethodException(names, e);
+        }
+        return null;
+    }
+
+    public static Method getMethod(Class<?> clazz, String... names)
+    {
+        try
+        {
+            Method[] methods = clazz.getDeclaredMethods();
+            for (Method method : methods) {
+                for (String methodName : names) {
+                    if (method.getName().equalsIgnoreCase(methodName))
+                    {
+                        method.setAccessible(true);
+                        return method;
+                    }
+                }
+            }
+        }
+        catch (Exception e)
+        {
+            throw new ReflectionHelper.UnableToFindMethodException(names, e);
+        }
+        return null;
+    }
+
+}