diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties
index ee54751a94..f765cdbae9 100644
--- a/core/assets/bundles/bundle.properties
+++ b/core/assets/bundles/bundle.properties
@@ -99,6 +99,7 @@ mod.enabled = [lightgray]Enabled
 mod.disabled = [scarlet]Disabled
 mod.disable = Disable
 mod.delete.error = Unable to delete mod. File may be in use.
+mod.requiresversion = [scarlet]Requires game version: [accent]{0}
 mod.missingdependencies = [scarlet]Missing dependencies: {0}
 mod.nowdisabled = [scarlet]Mod '{0}' is missing dependencies:[accent] {1}\n[lightgray]These mods need to be downloaded first.\nThis mod will be automatically disabled.
 mod.enable = Enable
diff --git a/core/src/io/anuke/mindustry/mod/Mods.java b/core/src/io/anuke/mindustry/mod/Mods.java
index 4fded5138e..77b81827ff 100644
--- a/core/src/io/anuke/mindustry/mod/Mods.java
+++ b/core/src/io/anuke/mindustry/mod/Mods.java
@@ -206,6 +206,7 @@ public class Mods implements Loadable{
         }
 
         resolveDependencies();
+
         //sort mods to make sure servers handle them properly.
         loaded.sort(Structs.comparing(m -> m.name));
 
@@ -213,6 +214,10 @@ public class Mods implements Loadable{
     }
 
     private void resolveDependencies(){
+        Array<LoadedMod> incompatible = loaded.select(m -> !m.isSupported());
+        loaded.removeAll(incompatible);
+        disabled.addAll(incompatible);
+
         for(LoadedMod mod : Array.<LoadedMod>withArrays(loaded, disabled)){
             updateDependencies(mod);
         }
@@ -572,6 +577,18 @@ public class Mods implements Loadable{
             return !missingDependencies.isEmpty();
         }
 
+        /** @return whether this mod is supported by the game verison */
+        public boolean isSupported(){
+            if(Version.build <= 0 || meta.minGameVersion == null) return true;
+            if(meta.minGameVersion.contains(".")){
+                String[] split = meta.minGameVersion.split("\\.");
+                if(split.length == 2){
+                    return Version.build >= Strings.parseInt(split[0], 0) && Version.revision >= Strings.parseInt(split[1], 0);
+                }
+            }
+            return Version.build >= Strings.parseInt(meta.minGameVersion, 0);
+        }
+
         @Override
         public String getSteamID(){
             return Core.settings.getString(name + "-steamid", null);
@@ -641,7 +658,7 @@ public class Mods implements Loadable{
 
     /** Plugin metadata information.*/
     public static class ModMeta{
-        public String name, author, description, version, main;
+        public String name, author, description, version, main, minGameVersion;
         public Array<String> dependencies = Array.with();
         /** Hidden mods are only server-side or client-side, and do not support adding new content. */
         public boolean hidden;
diff --git a/core/src/io/anuke/mindustry/ui/dialogs/ModsDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/ModsDialog.java
index 50164a7dff..ed8b3c5670 100644
--- a/core/src/io/anuke/mindustry/ui/dialogs/ModsDialog.java
+++ b/core/src/io/anuke/mindustry/ui/dialogs/ModsDialog.java
@@ -132,7 +132,7 @@ public class ModsDialog extends FloatingDialog{
                             title.addImageTextButton(mod.enabled() ? "$mod.disable" : "$mod.enable", mod.enabled() ? Icon.arrowDownSmall : Icon.arrowUpSmall, Styles.cleart, () -> {
                                 mods.setEnabled(mod, !mod.enabled());
                                 setup();
-                            }).height(50f).margin(8f).width(130f);
+                            }).height(50f).margin(8f).width(130f).disabled(!mod.isSupported());
 
                             if(steam && !mod.hasSteamID()){
                                 title.addImageButton(Icon.loadMapSmall, Styles.cleari, () -> {
@@ -161,7 +161,10 @@ public class ModsDialog extends FloatingDialog{
                             t.labelWrap("[lightgray]" + mod.meta.description).growX();
                             t.row();
                         }
-                        if(mod.hasUnmetDependencies()){
+                        if(!mod.isSupported()){
+                            t.labelWrap(Core.bundle.format("mod.requiresversion", mod.meta.minGameVersion)).growX();
+                            t.row();
+                        }else if(mod.hasUnmetDependencies()){
                             t.labelWrap(Core.bundle.format("mod.missingdependencies", mod.missingDependencies.toString(", "))).growX();
                             t.row();
                         }
diff --git a/fastlane/metadata/android/en-US/changelogs/29550.txt b/fastlane/metadata/android/en-US/changelogs/29550.txt
new file mode 100644
index 0000000000..53c981258b
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/29550.txt
@@ -0,0 +1,5 @@
+- Added fallback mod loading for poorly formatted old mods
+- Fixed infinite building range
+- Fixed impact reactors being able to blow up core on servers
+- Fixed liquid bridges passing backwards
+- Updated various translations