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
988 stars 47 forks source link

Problem: How to determine Game Vanilla state #1166

Closed Al12rs closed 6 months ago

Al12rs commented 6 months ago

Details

The App currently has no good way to determine the Vanilla state of the game.

This is something we need for:

Problem

Currently, we assume the initial state when a game is first managed to be vanilla, which is not actually going to be true all the time. The initial state is saved in the GameFiles mod. While the plan is to prevent users from disabling or deleting this mod, they will still be able to make changes to it presumably.

Problems:

How other managers approach this?

Other mod managers don't usually have this problem because they don't directly manage the game files.

These approaches allow both game updates and users installing mods manually if they so desire. On the flip side this means that the mod mangers can't rollback game updates that can potentially break user setups. In particular Vortex has the problem that newly created files are simply placed in the game folder and ignored instead of being manged. The MO2 approach of only considering things run through MO2 only works because of the fact it uses a VFS, and thus everything that changes the game folder outside the VFS (e.g. game updates) can be assumed to be an intended change to the vanilla layer. In the app, the game folder contains all the mods even while the App is closed, so changes to the folder can't be assumed to be done to the vanilla version.

Solutions:

erri120 commented 6 months ago

Other mod managers don't usually have this problem because they don't directly manage the game files.

Users will still have issues with other mod managers. As you mentioned, Vortex and MO2 just ignore the issue because their design allows it. This places all the responsibility of making sure the game is vanilla and doesn't update onto the user.

Let's break this down by starting with the initial state when the user first manages a game. Currently, we assume that this initial state is the vanilla state. We assume this because there is no feasible way of knowing otherwise. I'm not saying that it's impossible, just not feasible.

The "vanilla state" can be defined as the state of the files on disk after the user has freshly installed the game. To know the vanilla state, we'd have to know how the game was installed, or install the game automatically. Both of these options require the same thing: interacting with the installer. The installer would be one of the digital stores we support, like Steam, GOG, Epic Games Stores, Xbox Game Pass aka Microsoft Store, and others. While we might be able to support one store with enough time invested, we won't be able to support all of them. If we can't support all of them, then we can't make this a "core feature". A core feature would have to work with everything. Something like "launching the game" would be a core feature that has to work with everything.

Something that was tossed around a while back was saving the information about the "vanilla state" of a game in some external database. This has many issues. Firstly, we'd only be able to save and transmit a list of file names, sizes, and their hashes. We'd be able to tell the user, "your installation isn't vanilla" which is just the same as saying "make sure your installation is vanilla" which is what we currently do. Secondly, it's not feasible to know the "vanilla state" and put that in a database. The amount of permutations is too much. You'd have to install every version, with every language, with every combination of DLCs, on every store platform, on every supported operating system, to get all possible "vanilla states".

Assuming that the initial state is the vanilla state is the easiest and most straightforward solution. Every other solution comes with too many other issues that require too much time and resources to solve.

Next, let's talk about what happens when the game updates. Let's assume that the user manages the game with the App, they've installed some mods and applied their loadout. The next day, the game updates and they run the App again. We should be able to detect when the game updated. This would definitely require having a more robust system of identifying game versions, but if we had that, we could prompt the user about the game update and how to proceed. As far as the app is concerned, this would just piggyback off the ingest feature we already have. The user could choose for each individual changed file on how to proceed. We could even work with diffs to figure out the "new vanilla state":

If the user wants to upgrade the "base" of the loadout, aka the vanilla state, we could replace the game files with this new vanilla state.

Overall, we have more options when it comes to dealing with game updates. However, we should assume that the initial state is the vanilla state.

Al12rs commented 6 months ago

I think assuming the initial state is vanilla is fine if we allow users to update that state in some way, such are removing files from it or adding files to it.

This would help in these scenarios:

halgari commented 6 months ago

From Meeting notes on 4/8/2024:

BellCubeDev commented 6 months ago

Before a user adds a new game to manage, you may want a big huge warning modal beforehand explaining that the game must be in its vanilla state.