diff --git a/SCHIZO/Commands/DevCommands.cs b/SCHIZO/Commands/DevCommands.cs
index e0ad00de..da6e0a4c 100644
--- a/SCHIZO/Commands/DevCommands.cs
+++ b/SCHIZO/Commands/DevCommands.cs
@@ -137,4 +137,25 @@ public static object SetField(string typeName, string memberName, string valueSt
                 throw new InvalidOperationException("Unreachable");
         }
     }
+
+
+    [Command(Name = "dump_spawn_biomes",
+        DisplayName = "Dump Spawn Biomes",
+        Description = "List the biomes where a given techtype is registered to spawn",
+        RegisterConsoleCommand = true)]
+    public static string DumpSpawnBiomes(string classIdOrTechType)
+    {
+        string classId = Guid.TryParse(classIdOrTechType, out Guid guid) ? guid.ToString()
+            : UWE.Utils.TryParseEnum(classIdOrTechType, out TechType techType) ? CraftData.GetClassIdForTechType(techType)
+            : null;
+
+        if (classId is null) return MessageHelpers.TechTypeNotFound(classIdOrTechType);
+
+        CSVEntitySpawner spawner = GameObject.FindObjectOfType<CSVEntitySpawner>();
+        LootDistributionData lootData = spawner ? spawner.lootDistribution : BiomeHelpers.baseGameLootData;
+
+        return lootData.srcDistribution.TryGetValue(classId, out LootDistributionData.SrcData srcData)
+            ? string.Join(",", srcData.distribution.Select(bd => bd.biome))
+            : $"No data for {classIdOrTechType}";
+    }
 }
diff --git a/SCHIZO/Helpers/BiomeHelpers.cs b/SCHIZO/Helpers/BiomeHelpers.cs
index 70ceb82a..9c0ab33a 100644
--- a/SCHIZO/Helpers/BiomeHelpers.cs
+++ b/SCHIZO/Helpers/BiomeHelpers.cs
@@ -1,6 +1,8 @@
 using System;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Linq;
+using System.Text.RegularExpressions;
 
 namespace SCHIZO.Helpers;
 
@@ -14,11 +16,36 @@ public static IEnumerable<BiomeType> GetBiomesEndingInAny(params string[] filter
                 .Where(biome => filters.Any(f => biome.ToString().EndsWith(f)));
     }
 
-    public static IEnumerable<BiomeType> GetBiomesContainingAny(params string[] filters)
+    public static IEnumerable<BiomeType> GetBiomesMatching([StringSyntax("Regex")] params string[] filters)
     {
         if (filters.Length == 0) return [];
+
+        List<Regex> regexes = filters.Select(f => new Regex(f, RegexOptions.Compiled | RegexOptions.Singleline)).ToList();
         return Enum.GetValues(typeof(BiomeType))
             .Cast<BiomeType>()
-            .Where(biome => filters.Any(f => biome.ToString().Contains(f)));
+            .Where(biome => regexes.Any(f => f.IsMatch(biome.ToString())));
+    }
+
+    // unfortunately not accessible in main menu (when we register our creatures)
+    // hopefully it's not too big of an impact on load time
+    internal static readonly LootDistributionData baseGameLootData = LootDistributionData.Load("Balance/EntityDistributions");
+
+    public static IEnumerable<BiomeType> GetBiomesFor(IEnumerable<TechType> techTypes)
+    {
+        HashSet<BiomeType> set = [];
+        foreach (TechType tt in techTypes)
+        {
+            string classId = CraftData.GetClassIdForTechType(tt);
+            if (!baseGameLootData.srcDistribution.TryGetValue(classId, out LootDistributionData.SrcData srcData))
+            {
+                LOGGER.LogWarning($"Could not get biomes for {tt} - not in loot data!");
+                continue;
+            }
+
+            List<BiomeType> biomes = srcData.distribution.Select(bd => bd.biome).ToList();
+            set.AddRange(biomes);
+        }
+        LOGGER.LogWarning(string.Join(",", set.Select(b => b.ToString())));
+        return set;
     }
 }
diff --git a/SCHIZO/Resources/AssetBundles/Assets.cs b/SCHIZO/Resources/AssetBundles/Assets.cs
index e9c851ab..fe4acfee 100644
--- a/SCHIZO/Resources/AssetBundles/Assets.cs
+++ b/SCHIZO/Resources/AssetBundles/Assets.cs
@@ -12,7 +12,7 @@ namespace SCHIZO.Resources;
 
 public static class Assets
 {
-    private const int _rnd = 1702156462;
+    private const int _rnd = 1101407721;
 
     private static readonly UnityEngine.AssetBundle _a = ResourceManager.GetAssetBundle("assets");
 
diff --git a/SCHIZO/Resources/AssetBundles/assets b/SCHIZO/Resources/AssetBundles/assets
index 1473f63f..24b65780 100644
Binary files a/SCHIZO/Resources/AssetBundles/assets and b/SCHIZO/Resources/AssetBundles/assets differ
diff --git a/SCHIZO/Spawns/BiomeSpawnData.cs b/SCHIZO/Spawns/BiomeSpawnData.cs
index 3d5fbd9c..8628dcee 100644
--- a/SCHIZO/Spawns/BiomeSpawnData.cs
+++ b/SCHIZO/Spawns/BiomeSpawnData.cs
@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using SCHIZO.Helpers;
 
 namespace SCHIZO.Spawns;
@@ -16,7 +17,8 @@ public IEnumerable<BiomeType> GetBiomes()
             BiomeSpawnLocation.OpenWater => BiomeHelpers.GetBiomesEndingInAny("_Open", "_Open_CreatureOnly"),
             BiomeSpawnLocation.Surfaces => BiomeHelpers.GetBiomesEndingInAny("Ground", "Wall", "Floor", "Ledge",
                 "CaveEntrance", "CavePlants", "SandFlat", "ShellTunnelHuge", "Grass", "Sand", "Mountains", "Beach"),
-            BiomeSpawnLocation.Custom => BiomeHelpers.GetBiomesContainingAny(Data.biomeFilters),
+            BiomeSpawnLocation.Custom => BiomeHelpers.GetBiomesMatching(Data.biomeFilters),
+            BiomeSpawnLocation.CopyFromOthers => BiomeHelpers.GetBiomesFor(Data.copyFrom.Cast<TechType>()),
             _ => throw new InvalidOperationException($"Invalid spawn location {Location}")
         };
     }
diff --git a/Unity/Assets/Editor/Scripts/Extensions/SerializedPropertyExtensions.cs b/Unity/Assets/Editor/Scripts/Extensions/SerializedPropertyExtensions.cs
index b323eaf1..9708eb37 100644
--- a/Unity/Assets/Editor/Scripts/Extensions/SerializedPropertyExtensions.cs
+++ b/Unity/Assets/Editor/Scripts/Extensions/SerializedPropertyExtensions.cs
@@ -28,7 +28,7 @@ private static GetFieldInfo Setup()
         public static T GetCustomAttribute<T>(this SerializedProperty prop) where T : Attribute
         {
             FieldInfo info = prop.GetFieldInfoAndStaticType(out _);
-            return info.GetCustomAttribute<T>();
+            return info?.GetCustomAttribute<T>();
         }
 
         public static bool TryGetAttributeInHierarchy<T>(this SerializedProperty prop, out T attribute, out SerializedProperty ancestorWithAttribute) where T : Attribute
diff --git a/Unity/Assets/Mod/Anneel/Spawns.asset b/Unity/Assets/Mod/Anneel/Spawns.asset
index 2c482a1e..1f32b140 100644
--- a/Unity/Assets/Mod/Anneel/Spawns.asset
+++ b/Unity/Assets/Mod/Anneel/Spawns.asset
@@ -11,15 +11,17 @@ MonoBehaviour:
   m_EditorHideFlags: 0
   m_Script: {fileID: 11500000, guid: 31176ccc850eb4a40a6800859f45666b, type: 3}
   m_Name: Spawns
-  m_EditorClassIdentifier:
+  m_EditorClassIdentifier: 
   subnautica:
     spawn: 1
-    spawnLocation: 0
+    spawnLocation: 3
     biomeFilters: []
+    copyFrom: c8090000d3090000ce090000d1090000c5090000e3090000fa090000d7090000d8090000f2090000d5090000ca090000
   belowZero:
     spawn: 1
     spawnLocation: 0
     biomeFilters: []
+    copyFrom: 
   rules:
   - count: 1
     probability: 0.01
diff --git a/Unity/Assets/Mod/Ermfish/Spawns.asset b/Unity/Assets/Mod/Ermfish/Spawns.asset
index f0131c6f..8bb97b07 100644
--- a/Unity/Assets/Mod/Ermfish/Spawns.asset
+++ b/Unity/Assets/Mod/Ermfish/Spawns.asset
@@ -11,15 +11,17 @@ MonoBehaviour:
   m_EditorHideFlags: 0
   m_Script: {fileID: 11500000, guid: 31176ccc850eb4a40a6800859f45666b, type: 3}
   m_Name: Spawns
-  m_EditorClassIdentifier:
+  m_EditorClassIdentifier: 
   subnautica:
     spawn: 1
-    spawnLocation: 0
+    spawnLocation: 3
     biomeFilters: []
+    copyFrom: c8090000d3090000ce090000d1090000c5090000e3090000fa090000d7090000d8090000f2090000
   belowZero:
     spawn: 1
     spawnLocation: 0
     biomeFilters: []
+    copyFrom: 
   rules:
   - count: 1
     probability: 0.025
diff --git a/Unity/Assets/Mod/Ermshark/Spawns.asset b/Unity/Assets/Mod/Ermshark/Spawns.asset
index 7f396e3e..b6e6aa70 100644
--- a/Unity/Assets/Mod/Ermshark/Spawns.asset
+++ b/Unity/Assets/Mod/Ermshark/Spawns.asset
@@ -11,15 +11,17 @@ MonoBehaviour:
   m_EditorHideFlags: 0
   m_Script: {fileID: 11500000, guid: 31176ccc850eb4a40a6800859f45666b, type: 3}
   m_Name: Spawns
-  m_EditorClassIdentifier:
+  m_EditorClassIdentifier: 
   subnautica:
     spawn: 1
-    spawnLocation: 0
+    spawnLocation: 3
     biomeFilters: []
+    copyFrom: c8090000d3090000ce090000d1090000c5090000e3090000fa090000d7090000d8090000f2090000d5090000ca090000e6090000f3090000d0090000f1090000e7090000f7090000f8090000db090000
   belowZero:
     spawn: 1
     spawnLocation: 0
     biomeFilters: []
+    copyFrom: 
   rules:
   - count: 1
-    probability: 0.005
+    probability: 0.001
diff --git a/Unity/Assets/Scripts/SCHIZO/Spawns/BiomeSpawnData.cs b/Unity/Assets/Scripts/SCHIZO/Spawns/BiomeSpawnData.cs
index 7f73d863..b38003ac 100644
--- a/Unity/Assets/Scripts/SCHIZO/Spawns/BiomeSpawnData.cs
+++ b/Unity/Assets/Scripts/SCHIZO/Spawns/BiomeSpawnData.cs
@@ -1,6 +1,8 @@
 using System;
 using System.Collections.Generic;
 using JetBrains.Annotations;
+using SCHIZO.Interop.Subnautica.Enums;
+using SCHIZO.Registering;
 using TriInspector;
 using UnityEngine;
 
@@ -9,9 +11,9 @@ namespace SCHIZO.Spawns
     [CreateAssetMenu(menuName = "SCHIZO/Spawns/Biome Spawn Data")]
     public sealed partial class BiomeSpawnData : ScriptableObject
     {
-        [SerializeField, UsedImplicitly]
+        [SerializeField, UsedImplicitly, Game(Game.Subnautica)]
         private GameSpecificData subnautica;
-        [SerializeField, UsedImplicitly]
+        [SerializeField, UsedImplicitly, Game(Game.BelowZero)]
         private GameSpecificData belowZero;
 
         [TableList] public List<BiomeSpawnRule> rules;
@@ -24,6 +26,8 @@ public struct GameSpecificData
             public BiomeSpawnLocation spawnLocation;
             [EnableIf(nameof(spawn)), ShowIf(nameof(spawnLocation), BiomeSpawnLocation.Custom)]
             public string[] biomeFilters;
+            [EnableIf(nameof(spawn)), ShowIf(nameof(spawnLocation), BiomeSpawnLocation.CopyFromOthers)]
+            public TechType_All[] copyFrom;
         }
     }
 }
diff --git a/Unity/Assets/Scripts/SCHIZO/Spawns/BiomeSpawnLocation.cs b/Unity/Assets/Scripts/SCHIZO/Spawns/BiomeSpawnLocation.cs
index c106984c..6684c4ef 100644
--- a/Unity/Assets/Scripts/SCHIZO/Spawns/BiomeSpawnLocation.cs
+++ b/Unity/Assets/Scripts/SCHIZO/Spawns/BiomeSpawnLocation.cs
@@ -5,5 +5,6 @@ public enum BiomeSpawnLocation
         OpenWater,
         Surfaces,
         Custom,
+        CopyFromOthers,
     }
 }