Skip to content

Instantly share code, notes, and snippets.

@apple502j
Last active February 12, 2023 19:13
Show Gist options
  • Save apple502j/cf4be4efbf355ded3b7eb2c77b05779b to your computer and use it in GitHub Desktop.
Save apple502j/cf4be4efbf355ded3b7eb2c77b05779b to your computer and use it in GitHub Desktop.

fabric.mod.json (FMJ) version 2 proposal

FMJv2 will be a breaking change to FMJv1 with several incompatible changes.

Other Mod Loaders

Forge

Forge uses a TOML file, mods.toml, instead of JSON. Forge mod metadata file is very small, and all features except update check URL exist in FMJv1. Update checking should NOT be included in FMJv2, as that is beyond the scope of Fabric API/Loader. Mod Menu might be able to implement it.

Therefore, no feature from Forge metadata is worth bringing over.

Spigot

Spigot is not a modloader, but uses plugin.yml (YAML file) in a similar way. Apart from common fields:

  • Since Spigot is designed to be API-based with plugin compatibility in mind, it allows API version to be specified. Inapplicable to Fabric.
  • load field can change when the plugin loads, either startup or world load. The concept does not apply neatly to Fabric as it supports clients as well as dedicated servers. Fabric Lifecycle Events provides similar functionality.
  • prefix specifies the prefix used by logging. Since most, if not all, Fabric mods use the class name as the prefix, this is not a huge priority, and I am unsure if Fabric Loader can change this.
  • softdepend declares "soft dependency", i.e. non-required dependency. This corresponds to suggests.
  • loadbefore specifies the loading order. However, it is pretty clear Fabric does not take this approach.
  • libraries preview feature allows plugins to load Maven Central libraries. Fabric Loader is designed to work offline, so this is inapplicable.
  • commands declares registered commands. Fabric API provides this instead.
  • permissions declares permissions. Fabric mods usually use the vanilla permission level mechanics or uses a common unofficial mods.

Therefore, no feature from Spigot metadata is worth bringing over (aside from prefix, if it works at all).

Sponge

It seems like Sponge actually used annotations to define plugin metadata; however, the documentation mentions that JSON metadata is available in Sponge 8+. That said, Sponge offers several interesting fields:

  • loader specifies the loader version. This does exist in FMJv1, but is interesting nonetheless since others don't have this.
  • mappings specifies the used mappings. While Fabric mods are usually distributed with intermediary, this might be worth adding because of alternative mappings (e.g. Hashed-Mojmap) or for development environments where named mappings are used. Fabric Loader can exit early if the mapping is unsupported, which can reduce confusion from using dev jars in production.
  • global specifies global settings. Since a Sponge plugin can bundle multiple plugins (sort of like FAPI I think?) this applies to all plugins in it unless explicitly stated.
  • global.branding contains logo and icon. This is unlike FMJv1 which only specifies icon. Not sure if logo is useful.
  • global.dependencies can specify the dependency load order, which as I said is inapplicable to us.

mappings is the only change which could be worth porting to FMJv2.

Quilt

I couldn't find the documentation for quilt.mod.json, so I had to reverse-enginner the code.

  • plugins is probably for "loader plugins" which is not a thing in FL yet.
  • repositories: undocumented, not sure what the use is.
  • load_type: always, if_possible, or if_required. Mods in mod folder always load regardless; this affects JiJ.
  • intermediate_mappings specifies the intermediary mapping used, similar to Sponge's mappings.
  • metadata: Metadataception. ah yes. This contains the mod's name, contributors, etc.
  • mixin: for some reason, they made this singular. Why.
  • minecraft corresponds to environment in FMJ. However, the field rename is not something I'd suggest, since FL itself is not Minecraft-exclusive. Another change is use of dedicated_server instead of FMJ's server; this change should be ported as "server" is ambiguous.
  • depends had several changes. First, this is an array instead of an object. The array can have a string to represent any version, or an object with id and versions field. There is also optional field to declare if the dependency is optional (not sure what the difference between suggests is), reason string field, and unless field which I'm also unsure what the intended usage is. Versions are specified as one string or an array of strings ANDed.

Fabric should add the enhanced dependency declaration (except for unless and optional), rename server to dedicated_server within environment without renaminng the field, add intermediary field (see Sponge section), and potentially add load_type support.

Other Changes

Sided AccessWidener

It should be possible to specify multiple access wideners, potentially with side designation, like mixins:

{
  "accessWidener": [
    "modid.accesswidener",
    {
      "environment": "client",
      "file": "modid.client.accesswidener"
    }
  ]
}

Strings should also continue to work.

Dependency Info

When building, Loom automatically grabs dependency info from dependency jar's FMJ file, including its name, version, and URL. These should be appended to the dependent's FMJ file. FL can use this information to make the "missing dependency" screen more detailed.

@TheGlitch76
Copy link

The repositories block is vestigial from when we thought that we'd be adding automatic dependency downloading to our Loader soon:tm:, and for whatever reason decided to add it to the spec before we had a sketch of how it would actually work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment