Nexus-Mods / NexusMods.App

Home of the development of the Nexus Mods App
https://nexus-mods.github.io/NexusMods.App/
GNU General Public License v3.0
1.1k stars 52 forks source link

Multiple mods in one archive #266

Closed erri120 closed 1 year ago

erri120 commented 1 year ago

Most of our mod installation code assumes that there is one mod in one archive. The concept of a "mod" is defined by the game support code. I will use #42 as an example:

A SMAPI mod for Stardew Valley is defined by having a manifest.json file which points to either an entry DLL, if it's a C# mod, or references some content pack framework, if it's a content pack mod. Regardless of the type of mod, they all have the manifest.json file in common. Most archives will have a single manifest file: Example, which the installer will find and correctly process.

It is however possible that a mod author puts multiple SMAPI mods, within one archive: Example. In this case, the Nexus Mod Stardew Valley Expanded comes with multiple SMAPI Mods, a single C# mod and some content pack mods.

Stardew Valley Expanded requires all of those SMAPI Mods, however it is possible that some Nexus Mod has multiple optional Game Mods. Maestros of Synth by @halgari contains multiple Cyberpunk Mods within one archive that the user can mix and match.

We have to consider the following:

Instead of having an implementation of IModInstaller which looks at the entire archive and returns a list of files to be extracted, we could return a list of Game Mods and their associated files:

interface IModInstaller<TGameMod> where TGameMod : IGameMod
{
    IEnumerable<TGameMod> GetGameMods(Archive archive);
}
interface IGameMod
{
    AModFile[] ModFiles { get; }
}
record SMAPIMod(AModFile[] ModFiles, SMAPIManifest Manifest) : IGameMod;
class SMAPIModInstaller : IModInstaller<SMAPIMod>
{
    IEnumerable<SMAPIMod> GetGameMods(Archive archive)
    {
        // finds all manifest.json files
        // creates SMAPIMod for each manifest.json file
    }
}

A collection of Game Mods returned by the mod installer can then be presented to the user, if the collection has more than 1 item in it.

Aragas commented 1 year ago

This is also a case for Bannerlord. Huge overhauls like Game Of Thrones themed ones have a single archive with multiple game mods that are separated by whether they are pure content or script mods. They also contain each a manifest.json like file for distinction

halgari commented 1 year ago

For now I think we solve this by updating the IModInstaller API to allow multiple mods to be returned, the LoadoutManager can then tie these into a group via the mod metadata, once we have the metadata setup it becomes a visualization problem in the UI to express how this works to the user. I don't think this is too strange though, the user will select one archive and get multiple entries in the UI.

The implementation for this is then: