diff --git a/src/SMAPI/Framework/Models/SConfig.cs b/src/SMAPI/Framework/Models/SConfig.cs index ee2dc18d..158831a9 100644 --- a/src/SMAPI/Framework/Models/SConfig.cs +++ b/src/SMAPI/Framework/Models/SConfig.cs @@ -146,6 +146,12 @@ namespace StardewModdingAPI.Framework.Models custom[name] = value; } + if (this.ModsToLoadEarly.Any()) + custom[nameof(this.ModsToLoadEarly)] = $"[{string.Join(", ", this.ModsToLoadEarly)}]"; + + if (this.ModsToLoadLate.Any()) + custom[nameof(this.ModsToLoadLate)] = $"[{string.Join(", ", this.ModsToLoadLate)}]"; + if (!this.SuppressUpdateChecks.SetEquals(SConfig.DefaultSuppressUpdateChecks)) custom[nameof(this.SuppressUpdateChecks)] = $"[{string.Join(", ", this.SuppressUpdateChecks)}]"; diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index fb835002..7f564a28 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -427,18 +427,16 @@ namespace StardewModdingAPI.Framework { HashSet installedIds = new HashSet(mods.Select(p => p.Manifest.UniqueID), StringComparer.OrdinalIgnoreCase); - foreach (string modId in this.Settings.ModsToLoadEarly) - { - if (!installedIds.Contains(modId)) - this.Monitor.Log($" SMAPI configuration specifies a mod {modId} that should load early, but it could not be found or was skipped.", LogLevel.Warn); - } - foreach (string modId in this.Settings.ModsToLoadLate) - { - if (this.Settings.ModsToLoadEarly.Contains(modId)) - this.Monitor.Log($" SMAPI configuration specifies a mod {modId} that should load both early and late - this will be ignored.", LogLevel.Warn); - else if (!installedIds.Contains(modId)) - this.Monitor.Log($" SMAPI configuration specifies a mod {modId} that should load late, but it could not be found or was skipped.", LogLevel.Warn); - } + string[] missingEarlyMods = this.Settings.ModsToLoadEarly.Where(id => !installedIds.Contains(id)).OrderBy(p => p, StringComparer.OrdinalIgnoreCase).ToArray(); + string[] missingLateMods = this.Settings.ModsToLoadLate.Where(id => !installedIds.Contains(id)).OrderBy(p => p, StringComparer.OrdinalIgnoreCase).ToArray(); + string[] duplicateMods = this.Settings.ModsToLoadLate.Where(id => this.Settings.ModsToLoadEarly.Contains(id)).OrderBy(p => p, StringComparer.OrdinalIgnoreCase).ToArray(); + + if (missingEarlyMods.Any()) + this.Monitor.Log($" The 'smapi-internal/config.json' file lists mod IDs in {nameof(this.Settings.ModsToLoadEarly)} which aren't installed: '{string.Join("', '", missingEarlyMods)}'.", LogLevel.Warn); + if (missingLateMods.Any()) + this.Monitor.Log($" The 'smapi-internal/config.json' file lists mod IDs in {nameof(this.Settings.ModsToLoadLate)} which aren't installed: '{string.Join("', '", missingLateMods)}'.", LogLevel.Warn); + if (duplicateMods.Any()) + this.Monitor.Log($" The 'smapi-internal/config.json' file lists mod IDs which are in both {nameof(this.Settings.ModsToLoadEarly)} and {nameof(this.Settings.ModsToLoadLate)}: '{string.Join("', '", duplicateMods)}'. These will be loaded early.", LogLevel.Warn); } // load mods diff --git a/src/SMAPI/SMAPI.config.json b/src/SMAPI/SMAPI.config.json index 68645d24..0ab68a7d 100644 --- a/src/SMAPI/SMAPI.config.json +++ b/src/SMAPI/SMAPI.config.json @@ -144,12 +144,14 @@ copy all the settings, or you may cause bugs due to overridden changes in future ], /** - * The mod IDs SMAPI should try to load early, before any other mods not included in this list. + * The mod IDs SMAPI should load before any other mods (except those needed to load them) + * or after any other mods. + * + * This lets you manually fix the load order if needed, but this is a last resort — SMAPI + * automatically adjusts the load order based on mods' dependencies, so needing to manually + * edit the order is usually a problem with one or both mods' metadata that can be reported to + * the mod author. */ "ModsToLoadEarly": [], - - /** - * The mod IDs SMAPI should try to load late, after all other mods not included in this list. - */ "ModsToLoadLate": [] }