diff --git a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionClassLoader.java b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionClassLoader.java
index 3ce0a00ae..67363a40f 100644
--- a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionClassLoader.java
+++ b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionClassLoader.java
@@ -37,8 +37,8 @@ import java.util.Map;
 import java.util.Set;
 
 public class GeyserExtensionClassLoader extends URLClassLoader {
-    private GeyserExtensionLoader loader;
-    private Map<String, Class> classes = new HashMap<>();
+    private final GeyserExtensionLoader loader;
+    private final Map<String, Class> classes = new HashMap<>();
     public GeyserExtension extension;
 
     public GeyserExtensionClassLoader(GeyserExtensionLoader loader, ClassLoader parent, ExtensionDescription description, File file) throws InvalidExtensionException, MalformedURLException {
@@ -74,7 +74,7 @@ public class GeyserExtensionClassLoader extends URLClassLoader {
     }
 
     protected Class<?> findClass(String name, boolean checkGlobal) throws ClassNotFoundException {
-        if (name.startsWith("org.geysermc.geyser.") || name.startsWith("org.geysermc.connector.") || name.startsWith("net.minecraft.")) {
+        if (name.startsWith("org.geysermc.geyser.") || name.startsWith("org.geysermc.connector.") || name.startsWith("org.geysermc.platform.") || name.startsWith("org.geysermc.floodgate.") || name.startsWith("org.geysermc.api.") || name.startsWith("org.geysermc.processor.") || name.startsWith("net.minecraft.")) {
             throw new ClassNotFoundException(name);
         }
         Class<?> result = classes.get(name);
diff --git a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionDescription.java b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionDescription.java
index b14291b01..f8a3d9bbe 100644
--- a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionDescription.java
+++ b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionDescription.java
@@ -28,10 +28,7 @@ package org.geysermc.geyser.extension;
 import org.geysermc.geyser.api.extension.exception.InvalidDescriptionException;
 import org.yaml.snakeyaml.DumperOptions;
 import org.yaml.snakeyaml.Yaml;
-import java.io.BufferedReader;
-import java.io.IOException;
 import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.util.*;
 
 public class GeyserExtensionDescription implements org.geysermc.geyser.api.extension.ExtensionDescription {
@@ -48,13 +45,6 @@ public class GeyserExtensionDescription implements org.geysermc.geyser.api.exten
         this.loadMap(yaml.loadAs(inputStream, LinkedHashMap.class));
     }
 
-    private void loadString(String yamlString) throws InvalidDescriptionException {
-        DumperOptions dumperOptions = new DumperOptions();
-        dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
-        Yaml yaml = new Yaml(dumperOptions);
-        this.loadMap(yaml.loadAs(yamlString, LinkedHashMap.class));
-    }
-
     private void loadMap(Map<String, Object> yamlMap) throws InvalidDescriptionException {
         this.name = ((String) yamlMap.get("name")).replaceAll("[^A-Za-z0-9 _.-]", "");
         if (this.name.equals("")) {
diff --git a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionLoader.java b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionLoader.java
index cffd513a1..f029eb797 100644
--- a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionLoader.java
+++ b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionLoader.java
@@ -31,6 +31,7 @@ import org.geysermc.geyser.api.extension.ExtensionLoader;
 import org.geysermc.geyser.api.extension.GeyserExtension;
 import org.geysermc.geyser.api.extension.exception.InvalidDescriptionException;
 import org.geysermc.geyser.api.extension.exception.InvalidExtensionException;
+import org.geysermc.geyser.text.GeyserLocale;
 import java.io.*;
 import java.util.HashMap;
 import java.util.Map;
@@ -143,13 +144,13 @@ public class GeyserExtensionLoader implements ExtensionLoader {
     }
 
     void removeClass(String name) {
-        Class<?> clazz = classes.remove(name);
+        classes.remove(name);
     }
 
     @Override
     public void enableExtension(GeyserExtension extension) {
         if (!extension.isEnabled()) {
-            GeyserImpl.getInstance().getLogger().info("Enabled extension " + extension.description().name());
+            GeyserImpl.getInstance().getLogger().info(GeyserLocale.getLocaleStringLog("geyser.extensions.enable.success", extension.description().name()));
             extension.setEnabled(true);
         }
     }
@@ -157,7 +158,7 @@ public class GeyserExtensionLoader implements ExtensionLoader {
     @Override
     public void disableExtension(GeyserExtension extension) {
         if (extension.isEnabled()) {
-            GeyserImpl.getInstance().getLogger().info("Disabled extension " + extension.description().name());
+            GeyserImpl.getInstance().getLogger().info(GeyserLocale.getLocaleStringLog("geyser.extensions.disable.success", extension.description().name()));
             extension.setEnabled(false);
         }
     }
diff --git a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionLogger.java b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionLogger.java
index 225d6cda3..fe23417f8 100644
--- a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionLogger.java
+++ b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionLogger.java
@@ -29,8 +29,8 @@ import org.geysermc.geyser.GeyserLogger;
 import org.geysermc.geyser.api.extension.ExtensionLogger;
 
 public class GeyserExtensionLogger implements ExtensionLogger {
-    private GeyserLogger logger;
-    private String loggerPrefix;
+    private final GeyserLogger logger;
+    private final String loggerPrefix;
 
     public GeyserExtensionLogger(GeyserLogger logger, String prefix) {
         this.logger = logger;
diff --git a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionManager.java b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionManager.java
index 6dcfca0b5..169053182 100644
--- a/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionManager.java
+++ b/core/src/main/java/org/geysermc/geyser/extension/GeyserExtensionManager.java
@@ -28,6 +28,7 @@ package org.geysermc.geyser.extension;
 import org.geysermc.geyser.GeyserImpl;
 import org.geysermc.geyser.api.extension.ExtensionDescription;
 import org.geysermc.geyser.api.extension.GeyserExtension;
+import org.geysermc.geyser.text.GeyserLocale;
 import java.io.File;
 import java.lang.reflect.Constructor;
 import java.util.*;
@@ -38,12 +39,12 @@ public class GeyserExtensionManager {
     protected Map<Pattern, GeyserExtensionLoader> fileAssociations = new HashMap<>();
 
     public void init() {
-        GeyserImpl.getInstance().getLogger().info("Loading extensions...");
+        GeyserImpl.getInstance().getLogger().info(GeyserLocale.getLocaleStringLog("geyser.extensions.load.loading"));
 
         this.registerInterface(GeyserExtensionLoader.class);
         this.loadExtensions(new File("extensions"));
 
-        GeyserImpl.getInstance().getLogger().info("Loaded " + this.extensions.size() + " extension(s)");
+        GeyserImpl.getInstance().getLogger().info(GeyserLocale.getLocaleStringLog("geyser.extensions.load.done", this.extensions.size()));
     }
 
     public GeyserExtension getExtension(String name) {
@@ -102,7 +103,7 @@ public class GeyserExtensionManager {
                             }
                         }
                     } catch (Exception e) {
-                        GeyserImpl.getInstance().getLogger().error("Could not load extension", e);
+                        GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.extensions.load.failed"), e);
                         return null;
                     }
                 }
@@ -114,11 +115,11 @@ public class GeyserExtensionManager {
 
     public Map<String, GeyserExtension> loadExtensions(File dictionary) {
         if (GeyserImpl.VERSION.equalsIgnoreCase("dev")) { // If your IDE says this is always true, ignore it, it isn't.
-            GeyserImpl.getInstance().getLogger().error("Cannot load extensions in a development environment, aborting extension loading");
+            GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.extensions.load.failed_dev_environment"));
             return new HashMap<>();
         }
         if (!GeyserImpl.VERSION.contains(".")) {
-            GeyserImpl.getInstance().getLogger().error("Something went wrong with the Geyser version number, aborting extension loading");
+            GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.extensions.load.failed_version_number"));
             return new HashMap<>();
         }
 
@@ -153,7 +154,7 @@ public class GeyserExtensionManager {
                         String name = description.name();
 
                         if (extensions.containsKey(name) || this.getExtension(name) != null) {
-                            GeyserImpl.getInstance().getLogger().warning("Found duplicate extension '" + name + "', ignoring '" + file.getName() + "'");
+                            GeyserImpl.getInstance().getLogger().warning(GeyserLocale.getLocaleStringLog("geyser.extensions.load.duplicate", name, file.getName()));
                             continue;
                         }
 
@@ -163,7 +164,7 @@ public class GeyserExtensionManager {
                                 throw new IllegalArgumentException();
                             }
                         } catch (NullPointerException | IllegalArgumentException e) {
-                            GeyserImpl.getInstance().getLogger().error("Couldn't load extension " + name + ": Wrong API version format, should be 'majorVersion.minorVersion.patch', current version: " + apiVersion[0] + "." + apiVersion[1]);
+                            GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.extensions.load.failed_api_format", name, apiVersion[0] + "." + apiVersion[1]));
                             continue;
                         }
 
@@ -171,13 +172,13 @@ public class GeyserExtensionManager {
 
                         //Completely different API version
                         if (!Objects.equals(Integer.valueOf(versionArray[0]), Integer.valueOf(apiVersion[0]))) {
-                            GeyserImpl.getInstance().getLogger().error("Couldn't load extension " + name + ": Wrong API version, current version: " + apiVersion[0] + "." + apiVersion[1]);
+                            GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.extensions.load.failed_api_version", name, apiVersion[0] + "." + apiVersion[1]));
                             continue;
                         }
 
                         //If the extension requires new API features, being backwards compatible
                         if (Integer.parseInt(versionArray[1]) > Integer.parseInt(apiVersion[1])) {
-                            GeyserImpl.getInstance().getLogger().error("Couldn't load extension " + name + ": Wrong API version, current version: " + apiVersion[0] + "." + apiVersion[1]);
+                            GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.extensions.load.failed_api_version", name, apiVersion[0] + "." + apiVersion[1]));
                             continue;
                         }
 
@@ -185,7 +186,7 @@ public class GeyserExtensionManager {
                         loadedExtensions.put(name, this.loadExtension(file, this.fileAssociations));
                     }
                 } catch (Exception e) {
-                    GeyserImpl.getInstance().getLogger().error("Couldn't load " + file.getName() + " in folder " + dictionary.getAbsolutePath() + ": ", e);
+                    GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.extensions.load.failed_with_name", file.getName(), dictionary.getAbsolutePath()), e);
                 }
             }
         }
@@ -198,7 +199,7 @@ public class GeyserExtensionManager {
             try {
                 extension.extensionLoader().enableExtension(extension);
             } catch (Exception e) {
-                GeyserImpl.getInstance().getLogger().error("Error enabling extension " + extension.name() + ": ", e);
+                GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.extensions.enable.failed", extension.name()), e);
                 this.disableExtension(extension);
             }
         }
@@ -209,7 +210,7 @@ public class GeyserExtensionManager {
             try {
                 extension.extensionLoader().disableExtension(extension);
             } catch (Exception e) {
-                GeyserImpl.getInstance().getLogger().error("Error disabling extension " + extension.name() + ": ", e);
+                GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.extensions.disable.failed", extension.name()), e);
             }
         }
     }
diff --git a/core/src/main/resources/languages b/core/src/main/resources/languages
index 1a50238c1..94c185193 160000
--- a/core/src/main/resources/languages
+++ b/core/src/main/resources/languages
@@ -1 +1 @@
-Subproject commit 1a50238c1c743579a1dbd93c57d02b5da3be14fa
+Subproject commit 94c1851931f2319a7e7f42c2fe9066b78235bc39
diff --git a/core/src/main/resources/mappings b/core/src/main/resources/mappings
index 82ad7ba27..b60cfcdd4 160000
--- a/core/src/main/resources/mappings
+++ b/core/src/main/resources/mappings
@@ -1 +1 @@
-Subproject commit 82ad7ba279c68eb11a0b1a969c9efb3228c59227
+Subproject commit b60cfcdd40cd58a93143b489fc9153a347e48c41