This doc describe the instance update/undo design for modpack and instance locking.
User want to update the instance via new modpack version from modrinth and curseforge. At the same time, user might also have some tweak over the old version modpack.
Update the modpack content to instance can be tricky.
The launcher won't be able to fully solve the problem, but it will cover the major scenario of the modpack update.
Mods files are all in jar format, we can consider the file content is immutable. So, we can atomic compute the file change over the mod files.
Suppose we have the modpack with such content, adding three mods to the instance.
A.jar
B.jar
C.jar
Suppose the user edit the instance by adding two extra mods
A.jar
B.jar
C.jar
+ D.jar
+ E.jar
Suppose the new modpack has such files
A.jar
C.jar
X.jar
Let compute the diff between the original modpack and new modpack
+ X.jar
- C.jar
Now apply the diff to the user space to get the correct state
A.jar
B.jar
- C.jar
D.jar
E.jar
+ X.jar
Suppose the new modpack also add a file named D.jar
:
A.jar
B.jar
- C.jar
+ D.jar
+ X.jar
If the new D.jar
has the same content (sha1) with the file added by user, it will just keep the D.jar
there.
If the user's D.jar
and the new modpack's D.jar
are two different files, it will keep both of them but renaming user's D.jar
to a new identical name.
It will have CONFLICT
and 6-digit file sha1 hex in suffix.
A.jar
B.jar
- C.jar
+ D.jar
+ D.CONFLICT.abcdef.jar
+ X.jar
The launcher will hint user about any conflicts. The user can resolve them in mods file or edit the mod list in launcher.
The launcher should support undo between modpack version. This is just the revert operation of update.
After the upgrade, it should lock the new modpack content
A.jar
C.jar
X.jar
And the user space is:
A.jar
B.jar
D.jar
E.jar
X.jar
The undo should calculate the diff between new and old modpack content:
A.jar
+ B.jar
C.jar
- X.jar
Then apply the diff to the user space:
A.jar
B.jar
C.jar
D.jar
E.jar
- X.jar
And now the mods are recover to the state before update.
We start from user space with conflict
A.jar
B.jar
C.jar
D.jar
D.CONFLICT.abcdef.jar
X.jar
Apply the inverse operation
A.jar
B.jar
+ C.jar
- D.jar
- X.jar
it will become:
A.jar
B.jar
C.jar
- D.jar
D.CONFLICT.abcdef.jar
- X.jar
The launcher may or may not restore the conflict file name, as this file name won't affect the launching.
Most of the config file are in text. The V1 won't cover the diff apply over the text files if they are different. The launcher will create backup file beside the non-binary files.
This function should be OPTIONAL! User can disable the backup behavior to use git!
Suppose we have such config in the original modpack
configs/a.toml
configs/b.toml
.xyz/config.json
.abc/ConfigFile.ini
And the user edits two of them, and add a new extra text file
+ configs/a.toml
configs/b.toml
+ .xyz/config.json
.abc/ConfigFile.ini
+ custom.json
The new modpack edit an old file and add a new config file
+ configs/a.toml
configs/b.toml
+ configs/c.toml
.xyz/config.json
.abc/ConfigFile.ini
It will backup the user-edit config file and use the modpack config files:
+ configs/a.toml # this is the modpack version
+ configs/a.backup.toml # this is the user version
configs/b.toml
+ configs/c.toml
.xyz/config.json
.abc/ConfigFile.ini
custom.json
The undo won't work well as it will keep the .backup
file even after the undo.
As the design described above, we should save the file list with sha1 for each modpack version.
The implementation of file hashes will be:
- User import or download the modpack
- During the import, the launcher parses all the files with download url or zip url () and store the list, containing file sha1 and file path relative to the instance root.
- Store this metadata in our file metadata database.
In the instance config json (instance.json
), the current modpack file version id will be stored. It will use the modpack file version to determine which modpack file is the instance based on.
Suppose just have an instance, and it runs pretty well...
User want to add some mods to the instance, or want to update some mods. This can be risky. As new mod or update mod can break the Minecraft, crashing is a headache.
This problem is similar but different to the modpack-based instance update new version.
In both cases, users want to undo the change, but in this case, users want to lock the mod list (or config files) at the moment of instance working well.
So, the launcher should provide a functionality to lock mod list. (Why not config file also? Because that can be hard and easy to get wrong! For config file level backup, use git instead!)
Launcher will provide a function to create a lock file named instance-lock.json
(like package-lock.json
right?).
It will store the sha1
, filePath
(relative to the instance) list to the mods. It will also have the optional downloads
contains the download url of the file here.