Skip to content

Instantly share code, notes, and snippets.

@02JanDal
Last active January 3, 2016 21:39
Show Gist options
  • Select an option

  • Save 02JanDal/8523392 to your computer and use it in GitHub Desktop.

Select an option

Save 02JanDal/8523392 to your computer and use it in GitHub Desktop.
Proposal for a system unifying mods/jarmods/library patches/quickmods/vcs

Stages of work

  1. Basic patches. Only overwritting fields. Change forge and liteloader
  2. +/-
  3. In quickmod: mods
  4. Later: The Rest

A unified way of describing a Minecraft instance

This proposal is mostly about changes to the version.json file format, made so that these files can be patched together to form the information needed to create and run an instance. The idea is to only have this description inside the instance directory, thus making it easy to check in the instance to a VCS like Git.

Metadata like name, group, notes etc. will NOT be saved by the json file, and it is up to the implementation to keep them somewhere.

File structure:

<root>/
  +- instances/
  |      +- Vanilla/
  |      |     +- version.json
  |      |     +- patches/
  |      +- Customized/
  |            +- version.json
  |            +- mods.json
  |            +- custom.json
  |            +- patches/
  |                  +- net.minecraftforge.json
  |                  +- ftb.lite2.json
  +- mods/
  |      +- minecraftforge/
  |      |     +- forge-1.6.4-9.11.1.965-installer.jar
  |      |     +- ...
  |      +- mods/
  |            +- NotEnoughItems-1.6.1.8.jar
  |            +- ThermalExpansion-3.0.0.2.jar
  +- libraries/
         +- patches/
         |     +- optifine-1.6.4.jar
         +- net/
               +- minecraft/
                     +- launchwrapper/
                     |     +- 1.8/
                     |         +- launchwrapper-1.8.jar
                     +- minecraft/
                           +- 1.6.4/
                               +- minecraft-1.6.4.jar
                           +- 1.7.2/
                               +- minecraft-1.7.2.jar

The customized instance is based of FTB Lite 2, with some mods remove, some added, optifine and a patch applied to forge

JSON patching

All JSON files of an instance are patched together, beginning with version.json, then all files in patches/, in the order given in them (lower number = patched earlier, same number gives warning), and last the custom.json file. Generally the version.json file would describe the instance if it was vanilla. This file should not be edited and might be overwritten by the launcher. The files in patches/ are for forge, liteloader, modpacks etc. They too should generally not be edited by the user and might be overwritten by the launcher. The one file the user should edit is custom.json this is loaded last in the chain, and therefore it can rearrange/overwrite anything.

In the scenario of a modpack, the there would be a modpack file in patches/ that would describe the modpack (mods etc.). The user could then "edit" the modpack by adding/removing mods in the custom.json file.

Removing, adding and overwritting

The general rules: If a field is prefixed with a '+' the value is added to the existing values (a string would be appended, a list would be merged etc.). Prefixing with '-' means removing (it will try to find the value and if found remove it). No prefix means the field will be overwritten.

New fields

patches

Can be applied to both libraries and the root element (will be applied to minecraft itself). Can be either a filename (should exist in libraries/patches/) or a object with a QuickMod UID => version mapping (one mod per object).

mods

Describes a set of mods, same internal syntax as patches, but filenames should be in mods/mods/

order

Used in files in patches/. Specifies in which order patches are "applied". A patch with the order 1 is applied before a patch with the order 5. Same numbers will throw a warning.

insert

Used for libraries and patches. Specifies where in the list they will be put.

For any of the insert types where a name is used '*' can be used as a wildcraft anywhere in the name

Possible values:

beginning

Add at the beginning of the list. For patches and custom.json all "beginning" objects will be applied in "reverse", which means they will end up in the same order as in the patch file

ending

Append

apply

Search for an existing entry with the name and apply any new info (+, -, etc) to it. If no such entry exists do nothing.

An object

An object with TYPE => name mappings, where TYPE can be any either "before" or "after".

Launching

  1. Download libraries as usual
  2. Apply library patches. QuickMod ones may be downloaded, and those that can not be found asked for.
  3. Download QuickMod mods and ask the user for filename mods it cannot find, like for patches.
  4. Add mods etc. to the classpath and launch

The custom.json file

The custom.json file would be the ONE AND ONLY file that the user may touch. This is also the file which the launcher would change if the user adds/removes mods etc., the content of all the other files should stay, and may be overwritten by the launcher at any time.

What happens if...

...the user puts a mod in /minecraft/mods?

The launcher will detect it, give the user a warning and then move it to mods/mods/ and add an entry for it in custom.json

...a mod/library/patch is not available on launch and the user can not supply it?

For mods a warning is displayed with the option to ignore it, for libraries and patches an error is shown and the launch will be aborted.

...the user changes something in version.json or in patches/?

The launcher can and SHOULD overwrite those changes before dealing with the files.

The End

Most JSON files are listed below

{
"+minecraftArguments": " --tweakClass cpw.mods.fml.common.launcher.FMLTweaker",
"mainClass": "net.minecraft.launchwrapper.Launch",
"+libraries": [
{
"name": "net.minecraftforge:minecraftforge:9.11.1.965",
"insert": "apply",
"patches": [
"rouge-forge-patch-1.0.zip",
{ "a-bit-less-rouge": "2.0" }
]
}
],
"patches": [
"optifine-1.6.4.jar"
],
"+mods": [
{ "buildcraft.BuildCraft": "4.1.2" }
],
"-mods": [
{ "profmobius.Opis": "1.0.4" }
]
}
{
"order": 50,
"+mods": [
{ "teamcofh.ThermalExpansion": "3.0.0.2" },
{ "teamcofh.CoFHCore": "2.0.0.2" },
{ "profmobius.Opis": "1.0.4" }
]
}
{
"order": 1,
"+minecraftArguments": "--tweakClass cpw.mods.fml.common.launcher.FMLTweaker",
"mainClass": "net.minecraft.launchwrapper.Launch",
"+libraries": [
{
"MMC-absoluteUrl": "http://files.minecraftforge.net/maven/net/minecraftforge/forge/1.6.4-9.11.1.965/forge-1.6.4-9.11.1.965-universal.jar",
"name": "net.minecraftforge:minecraftforge:9.11.1.965",
"url": "http://files.minecraftforge.net/maven/",
"insert": "beginning"
},
{
"name": "net.minecraft:launchwrapper:1.8",
"insert": "beginning"
},
{
"name": "org.ow2.asm:asm-all:4.1",
"insert": "beginning"
},
{
"MMC-hint": "forge-pack-xz",
"name": "org.scala-lang:scala-library:2.10.2",
"url": "http://files.minecraftforge.net/maven/",
"insert": "beginning"
},
{
"MMC-hint": "forge-pack-xz",
"name": "org.scala-lang:scala-compiler:2.10.2",
"url": "http://files.minecraftforge.net/maven/",
"insert": "beginning"
},
{
"name": "lzma:lzma:0.0.1",
"insert": "beginning"
}
]
}
{
"id": "1.6.4",
"time": "2013-09-19T17:52:37+02:00",
"releaseTime": "2013-09-19T17:52:37+02:00",
"type": "release",
"processArguments": "username_session_version",
"minecraftArguments": "--username ${auth_player_name} --session ${auth_session} --version ${version_name} --gameDir ${game_directory} --assetsDir ${game_assets}",
"minimumLauncherVersion": 4,
"libraries": [
{
"name": "net.sf.jopt-simple:jopt-simple:4.5"
},
{
"name": "com.paulscode:codecjorbis:20101023"
},
{
"name": "com.paulscode:codecwav:20101023"
},
{
"name": "com.paulscode:libraryjavasound:20101123"
},
{
"name": "com.paulscode:librarylwjglopenal:20100824"
},
{
"name": "com.paulscode:soundsystem:20120107"
},
{
"name": "argo:argo:2.25_fixed"
},
{
"name": "org.bouncycastle:bcprov-jdk15on:1.47"
},
{
"name": "com.google.guava:guava:14.0"
},
{
"name": "org.apache.commons:commons-lang3:3.1"
},
{
"name": "commons-io:commons-io:2.4"
},
{
"name": "net.java.jinput:jinput:2.0.5"
},
{
"name": "net.java.jutils:jutils:1.0.0"
},
{
"name": "com.google.code.gson:gson:2.2.2"
},
{
"name": "org.lwjgl.lwjgl:lwjgl:2.9.0",
"rules": [
{
"action": "allow"
},
{
"action": "disallow",
"os": {
"name": "osx",
"version": "^10\\.5\\.\\d$"
}
}
]
},
{
"name": "org.lwjgl.lwjgl:lwjgl_util:2.9.0",
"rules": [
{
"action": "allow"
},
{
"action": "disallow",
"os": {
"name": "osx",
"version": "^10\\.5\\.\\d$"
}
}
]
},
{
"name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.0",
"natives": {
"linux": "natives-linux",
"windows": "natives-windows",
"osx": "natives-osx"
},
"extract": {
"exclude": [
"META-INF/"
]
},
"rules": [
{
"action": "allow"
},
{
"action": "disallow",
"os": {
"name": "osx",
"version": "^10\\.5\\.\\d$"
}
}
]
},
{
"name": "org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20130708-debug3",
"rules": [
{
"action": "allow",
"os": {
"name": "osx",
"version": "^10\\.5\\.\\d$"
}
}
]
},
{
"name": "org.lwjgl.lwjgl:lwjgl_util:2.9.1-nightly-20130708-debug3",
"rules": [
{
"action": "allow",
"os": {
"name": "osx",
"version": "^10\\.5\\.\\d$"
}
}
]
},
{
"name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.1-nightly-20130708-debug3",
"natives": {
"linux": "natives-linux",
"windows": "natives-windows",
"osx": "natives-osx"
},
"extract": {
"exclude": [
"META-INF/"
]
},
"rules": [
{
"action": "allow",
"os": {
"name": "osx",
"version": "^10\\.5\\.\\d$"
}
}
]
},
{
"name": "net.java.jinput:jinput-platform:2.0.5",
"natives": {
"linux": "natives-linux",
"windows": "natives-windows",
"osx": "natives-osx"
},
"extract": {
"exclude": [
"META-INF/"
]
}
}
],
"mainClass": "net.minecraft.client.main.Main"
}
{
"id": "1.7.2",
"time": "2013-10-25T15:00:00+02:00",
"releaseTime": "2013-10-25T15:00:00+02:00",
"type": "release",
"minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${game_assets} --uuid ${auth_uuid} --accessToken ${auth_access_token}",
"minimumLauncherVersion": 9,
"libraries": [
{
"name": "java3d:vecmath:1.3.1"
},
{
"name": "net.sf.trove4j:trove4j:3.0.3"
},
{
"name": "com.ibm.icu:icu4j-core-mojang:51.2"
},
{
"name": "net.sf.jopt-simple:jopt-simple:4.5"
},
{
"name": "com.paulscode:codecjorbis:20101023"
},
{
"name": "com.paulscode:codecwav:20101023"
},
{
"name": "com.paulscode:libraryjavasound:20101123"
},
{
"name": "com.paulscode:librarylwjglopenal:20100824"
},
{
"name": "com.paulscode:soundsystem:20120107"
},
{
"name": "io.netty:netty-all:4.0.10.Final"
},
{
"name": "com.google.guava:guava:15.0"
},
{
"name": "org.apache.commons:commons-lang3:3.1"
},
{
"name": "commons-io:commons-io:2.4"
},
{
"name": "net.java.jinput:jinput:2.0.5"
},
{
"name": "net.java.jutils:jutils:1.0.0"
},
{
"name": "com.google.code.gson:gson:2.2.4"
},
{
"name": "com.mojang:authlib:1.3"
},
{
"name": "org.apache.logging.log4j:log4j-api:2.0-beta9"
},
{
"name": "org.apache.logging.log4j:log4j-core:2.0-beta9"
},
{
"name": "org.lwjgl.lwjgl:lwjgl:2.9.0",
"rules": [
{
"action": "allow"
},
{
"action": "disallow",
"os": {
"name": "osx"
}
}
]
},
{
"name": "org.lwjgl.lwjgl:lwjgl_util:2.9.0",
"rules": [
{
"action": "allow"
},
{
"action": "disallow",
"os": {
"name": "osx"
}
}
]
},
{
"name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.0",
"natives": {
"linux": "natives-linux",
"windows": "natives-windows"
},
"extract": {
"exclude": [
"META-INF/"
]
},
"rules": [
{
"action": "allow"
},
{
"action": "disallow",
"os": {
"name": "osx"
}
}
]
},
{
"name": "org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20131017",
"rules": [
{
"action": "allow",
"os": {
"name": "osx"
}
}
]
},
{
"name": "org.lwjgl.lwjgl:lwjgl_util:2.9.1-nightly-20131017",
"rules": [
{
"action": "allow",
"os": {
"name": "osx"
}
}
]
},
{
"name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.1-nightly-20131017",
"natives": {
"osx": "natives-osx"
},
"extract": {
"exclude": [
"META-INF/"
]
},
"rules": [
{
"action": "allow",
"os": {
"name": "osx"
}
}
]
},
{
"name": "net.java.jinput:jinput-platform:2.0.5",
"natives": {
"linux": "natives-linux",
"windows": "natives-windows",
"osx": "natives-osx"
},
"extract": {
"exclude": [
"META-INF/"
]
}
}
],
"mainClass": "net.minecraft.client.main.Main"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment