{"action":"created","issue":{"url":"https://api.github.com/repos/MinecraftForge/FML/issues/637","labels_url":"https://api.github.com/repos/MinecraftForge/FML/issues/637/labels{/name}","comments_url":"https://api.github.com/repos/MinecraftForge/FML/issues/637/comments","events_url":"https://api.github.com/repos/MinecraftForge/FML/issues/637/events","html_url":"https://github.com/MinecraftForge/FML/issues/637","id":67962175,"number":637,"title":"Suggestion: Improved JSON format for mod info","user":{"login":"rbuckton","id":3902892,"avatar_url":"https://avatars.githubusercontent.com/u/3902892?v=3","gravatar_id":"","url":"https://api.github.com/users/rbuckton","html_url":"https://github.com/rbuckton","followers_url":"https://api.github.com/users/rbuckton/followers","following_url":"https://api.github.com/users/rbuckton/following{/other_user}","gists_url":"https://api.github.com/users/rbuckton/gists{/gist_id}","starred_url":"https://api.github.com/users/rbuckton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rbuckton/subscriptions","organizations_url":"https://api.github.com/users/rbuckton/orgs","repos_url":"https://api.github.com/users/rbuckton/repos","events_url":"https://api.github.com/users/rbuckton/events{/privacy}","received_events_url":"https://api.github.com/users/rbuckton/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-04-12T21:31:51Z","updated_at":"2015-04-13T20:18:11Z","closed_at":null,"body":"# Introduction\r\nAfter having spent quite a bit of time working with [NodeJS](http://nodejs.org) and [NPM](http://npmjs.org), I've become quite impressed with the power and simplicity of the [package.json](https://docs.npmjs.com/files/package.json) file format. I've noticed that FML internally uses a somewhat similar format in the form of the [mcmod.info](https://github.com/MinecraftForge/FML/wiki/FML-mod-information-file) file, but I've found that there are a few drawbacks to the format:\r\n\r\n* While most mods embed `mcmod.info` in the JAR, there doesn't seem to be a public repository of these files. As a result, each mod needs to write its own update checking logic (or rely on a shared library).\r\n* The \"version\" field of `mcmod.info` is arbitrary. As a result, update checking logic must be unique to the version format used by the mod author.\r\n* The \"dependencies\" and \"requiredMods\" fields of `mcmod.info` do not specify version information.\r\n\r\nThe `package.json` format used by nodejs shares similar characteristics with `mcmod.info`, but provides some additional capabilities:\r\n\r\n* The \"version\" field requires a canonical format, via [semantic versioning](http://semver.org).\r\n* The \"dependencies\" field is a map of required dependencies to their minimal version, using a specialized format for specifying version ranges.\r\n* The \"repository\" field contains information about where to clone or contribute to the package if it is open source.\r\n* The \"bugs\" field contains information about where to file bugs against the package.\r\n* The \"directories\" and \"files\" fields contain information about the contents of the package.\r\n\r\n# Proposal\r\nI propose that a new JSON format be introduced for FML mods. This format would use the following structure:\r\n\r\n> NOTE: The following listing uses TypeScript interfaces to describe the structure of the JSON file.\r\n> * The `?` token following a field name marks the field as optional.\r\n> * The `|` token between types means the field must be either of the types.\r\n> * The `[]` tokens following a type or parenthesized type indicate an array.\r\n\r\n> NOTE: Not all of the existing fields from `mcmod.info` are listed below, and some have been renamed or moved. This does not mean they should be lost, but rather merged into this format as appropriate.\r\n\r\n```ts\r\n// The primary structure for the JSON file\r\ninterface Mod {\r\n  // The name of the mod, used as a key for dependencies (previously \"modid\")\r\n  name: string;\r\n\r\n  // A descriptive name for the mod (previously \"name\")\r\n  title?: string;\r\n\r\n  // A long description for the mod\r\n  description?: string;\r\n\r\n  // Additional keywords or tags for the mod\r\n  keywords?: string[];\r\n\r\n  // The semantic version of the mod: http://semver.org\r\n  version: string;\r\n\r\n  // The primary author of the mod (previously \"credits\"/\"authorList\"). \r\n  author?: string | Person;\r\n\r\n  // Additional contributors to the mod (previously \"authorList\")\r\n  contributors?: (string | Person)[];\r\n\r\n  // A url to the homepage for the mod\r\n  homepage?: string;\r\n\r\n  // A url to download the binary version of the mod\r\n  url?: string | FileResource;\r\n\r\n  // Urls to download additional resources for the mod\r\n  urls?: (string | FileResource)[];\r\n\r\n  // The source code repository for the mod, if it is open source\r\n  repository?: string | Resource;\r\n\r\n  // The means with which users can file bugs\r\n  bugs?: BugTracker\r\n\r\n  // Required dependencies for the mod (previously \"dependencies\", \"requiredMods\", \"mcversion\")\r\n  dependencies?: DependencyMap;\r\n\r\n  // Optional dependencies for the mod\r\n  optionalDependencies?: DependencyMap\r\n\r\n  // Developer dependencies for the mod\r\n  devDependencies?: DependencyMap;\r\n\r\n  // License information for the mod. See https://spdx.org/licenses/\r\n  license?: string;\r\n\r\n  // Directories in the mod (under the mods/[mod name] folder)\r\n  directories?: string[];\r\n\r\n  // Files in the mod (under the mods/[mod name] folder)\r\n  files?: string;\r\n\r\n  // Extensibility for future updates\r\n  [key: string]: any;\r\n}\r\n\r\n// Extended information about a Person\r\ninterface Person {\r\n  // The display name for the person\r\n  name: string;\r\n\r\n  // The email for the person \r\n  email?: string;\r\n\r\n  // A url for the person (homepage, blog, profile, etc.)\r\n  url?: string;\r\n}\r\n\r\n// Extended information about a url resource\r\ninterface Resource {\r\n  // What type of resource is this? A file? A feed? A git repository?\r\n  type: string;\r\n\r\n  // The url to the resource\r\n  url: string;\r\n}\r\n\r\n// Extended information about a file url resource\r\ninterface FileResource extends Resource {\r\n  // The MD5 hash of the file resource (in hexadecimal)\r\n  md5?: string;\r\n  // The SHA1 hash of the file resource (in hexadecimal)\r\n  sha1?: string;\r\n}\r\n\r\n// Extended information about a bug tracker\r\ninterface BugTracker {\r\n  // A url to a public bug tracker\r\n  url?: string;\r\n\r\n  // An email for bug reports\r\n  email?: string;\r\n}\r\n\r\n// A key-value map for dependencies to the required version spec:\r\ninterface DependencyMap {\r\n  [dependency: string]: string;\r\n}\r\n```\r\n\r\n## Dependencies\r\nA dependency can specify the version range required (useful both for version testing when loading the mod, and to allow loaders or mod management tools to check for updates and version mismatches. For an example of version ranges, see https://docs.npmjs.com/misc/semver.\r\n\r\n## Example\r\nHere is an example from converting the mcmod.info for Thermal Foundation:\r\n```json\r\n{\r\n  \"name\": \"ThermalFoundation\",\r\n  \"title\": \"Thermal Foundation\",\r\n  \"description\": \"The foundation of a Thermally enhanced world!\",\r\n  \"version\": \"1.0.0-RC4+58\",\r\n  \"author\": \"TeamCoFH\",\r\n  \"contributors\": [\r\n    \"KingLemming\",\r\n    \"skyboy026\",\r\n    \"ZeldoKavira\"\r\n  ],\r\n  \"homepage\": \"http://www.curse.com/mc-mods/minecraft/222880-thermal-foundation\",\r\n  \"dependencies\": {\r\n    \"Minecraft\": \"1.7.10\",\r\n    \"MinecraftForge\": \"10.13.2\",\r\n    \"CoFHCore\": \"3.0.0\"\r\n  },\r\n  \"repository\": {\r\n    \"type\": \"git\",\r\n    \"url\": \"https://github.com/CoFH/ThermalFoundation\"\r\n  },\r\n  \"bugs\": {\r\n    \"url\": \"https://github.com/CoFH/Feedback/issues\"\r\n  },\r\n  \"files\": [\r\n    \"ThermalFoundation-[1.7.10]1.0.0RC4-58.jar\"\r\n  ]\r\n}\r\n```\r\n\r\nAnd here is an example for Forge:\r\n```json\r\n{\r\n  \"name\": \"MinecraftForage\",\r\n  \"title\": \"Forge\",\r\n  \"version\": \"10.13.2+1291\",\r\n  \"dependencies\": {\r\n    \"Minecraft\": \"1.7.10\"\r\n  },  \r\n  \"homepage\": \"http://files.minecraftforge.net/\",\r\n  \"author\": \"LexManos\",\r\n  \"urls\": [\r\n    {\r\n      \"type\": \"Universal\",\r\n      \"url\": \"http://files.minecraftforge.net/maven/net/minecraftforge/forge/1.7.10-10.13.2.1291/forge-1.7.10-10.13.2.1291-universal.jar\",\r\n      \"md5\": \"e71e88c744588fdad48d3b3beb4935fc\"\r\n    },\r\n    {\r\n      \"type\": \"Installer-win\",\r\n      \"url\": \"http://files.minecraftforge.net/maven/net/minecraftforge/forge/1.7.10-10.13.2.1291/forge-1.7.10-10.13.2.1291-installer-win.exe\",\r\n      \"md5\": \"0b8598a75955dedf99a56e39c5c721ce\"\r\n    },\r\n    {\r\n      \"type\": \"Changelog\",\r\n      \"url\": \"http://files.minecraftforge.net/maven/net/minecraftforge/forge/1.7.10-10.13.2.1291/forge-1.7.10-10.13.2.1291-changelog.txt\"\r\n    }\r\n  ],\r\n  \"repository\": {\r\n    \"type\": \"git\",\r\n    \"url\": \"https://github.com/MinecraftForge/MinecraftForge\"\r\n  },\r\n  \"bugs\": {\r\n    \"url\": \"https://github.com/MinecraftForge/MinecraftForge/issues\"\r\n  }\r\n}\r\n```\r\n\r\n## Benefits\r\nBy adopting this format, and assuming a central repository to which mod authors could publish these files, in addition to embedding them in the JAR, there would be a number of benefits:\r\n\r\n* Mod authors can easily specify version ranges for dependencies.\r\n* Mod authors have control over how their mods are downloaded (automatic updates, or require the user to navigate to a home page or an adfly link, etc).\r\n* A central repository (like http://modlist.mcf.li, Curse, or something else similar to http://npmjs.org) could manage these dependencies.\r\n* A tool similar to [npm](http://npmjs.org) could be used to install and update mods on a server or client\r\n* Server operators could easily update their servers and ensure compatible versions of dependent mods are updated all at once.\r\n* Clients could easily download mods by following links in the JSON files stored either in a central repository or from a Minecraft server."},"comment":{"url":"https://api.github.com/repos/MinecraftForge/FML/issues/comments/92485992","html_url":"https://github.com/MinecraftForge/FML/issues/637#issuecomment-92485992","issue_url":"https://api.github.com/repos/MinecraftForge/FML/issues/637","id":92485992,"user":{"login":"cpw","id":1217211,"avatar_url":"https://avatars.githubusercontent.com/u/1217211?v=3","gravatar_id":"","url":"https://api.github.com/users/cpw","html_url":"https://github.com/cpw","followers_url":"https://api.github.com/users/cpw/followers","following_url":"https://api.github.com/users/cpw/following{/other_user}","gists_url":"https://api.github.com/users/cpw/gists{/gist_id}","starred_url":"https://api.github.com/users/cpw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cpw/subscriptions","organizations_url":"https://api.github.com/users/cpw/orgs","repos_url":"https://api.github.com/users/cpw/repos","events_url":"https://api.github.com/users/cpw/events{/privacy}","received_events_url":"https://api.github.com/users/cpw/received_events","type":"User","site_admin":false},"created_at":"2015-04-13T20:18:11Z","updated_at":"2015-04-13T20:18:11Z","body":"Semver is definitely a long term goal for versioning.."}}