diff --git a/osu.Game/Utils/ModUtils.cs b/osu.Game/Utils/ModUtils.cs index 40db981ef0..f11a06e3be 100644 --- a/osu.Game/Utils/ModUtils.cs +++ b/osu.Game/Utils/ModUtils.cs @@ -115,12 +115,15 @@ namespace osu.Game.Utils { mods = mods.ToArray(); - // exclude multi mods from compatibility checks. - // the loop below automatically marks all multi mods as not valid for gameplay anyway. - if (!CheckCompatibleSet(mods.Where(m => !(m is MultiMod)), out invalidMods)) + // checking compatibility of multi mods would try to flatten them and return incompatible mods. + // in gameplay context, we never want MultiMod selected in the first place, therefore check against it first. + if (!checkValid(mods, m => !(m is MultiMod), out invalidMods)) return false; - return checkValid(mods, m => m.Type != ModType.System && m.HasImplementation && !(m is MultiMod), out invalidMods); + if (!CheckCompatibleSet(mods, out invalidMods)) + return false; + + return checkValid(mods, m => m.Type != ModType.System && m.HasImplementation, out invalidMods); } /// @@ -133,10 +136,15 @@ namespace osu.Game.Utils { mods = mods.ToArray(); + // checking compatibility of multi mods would try to flatten them and return incompatible mods. + // in gameplay context, we never want MultiMod selected in the first place, therefore check against it first. + if (!checkValid(mods, m => !(m is MultiMod), out invalidMods)) + return false; + if (!CheckCompatibleSet(mods, out invalidMods)) return false; - return checkValid(mods, m => m.IsPlayable(ModUsage.MultiplayerGlobal), out invalidMods); + return checkValid(mods, m => m.Type != ModType.System && m.HasImplementation && m.IsPlayable(ModUsage.MultiplayerGlobal), out invalidMods); } /// @@ -146,7 +154,7 @@ namespace osu.Game.Utils /// Invalid mods, if any were found. Will be null if all mods were valid. /// Whether the input mods were all valid. If false, will contain all invalid entries. public static bool CheckValidFreeModsForMultiplayer(IEnumerable mods, [NotNullWhen(false)] out List? invalidMods) - => checkValid(mods, m => m.IsPlayable(ModUsage.MultiplayerLocal), out invalidMods); + => checkValid(mods, m => m.Type != ModType.System && m.HasImplementation && m.IsPlayable(ModUsage.MultiplayerLocal) && !(m is MultiMod), out invalidMods); private static bool checkValid(IEnumerable mods, Predicate valid, [NotNullWhen(false)] out List? invalidMods) {