Skip to content

Instantly share code, notes, and snippets.

@kvverti
Last active June 24, 2023 01:48
Show Gist options
  • Save kvverti/3fc6a05d974210f785a9a751d5e0ae28 to your computer and use it in GitHub Desktop.
Save kvverti/3fc6a05d974210f785a9a751d5e0ae28 to your computer and use it in GitHub Desktop.
The Fabric API Problem

Fabric API

Fabric API is supposed to be modular. This means that mod devs should be able to pick and choose which Fabric API modules to depend on in their mods, both in the development environment and in production.

Fabric API is also supposed to be just another mod. Fabric API should not have special support in Fabric tooling, nor should it be a required install for players. Basically, Fabric API is simply a collection of mostly independent modules that happen to be maintained by the same organization that maintains Fabric tooling.

The Problem

The fabric example mod contains a hard dependency on the entire Fabric API. Since most mod devs do not remove this dependency, most players have to download an additional mod (Fabric API) in order to play a Fabric mod, which many players do not expect. This means mod devs often assume that players have installed Fabric API in the production evnironment.

The reason that most mod devs do not depend on and include the specific Fabric API modules they use is twofold.

  1. Depending on the entire Fabric API is the default provided in the fabric example mod
  2. Depending on specific modules is difficult because the modules do not have Minecraft version information attached

I have been told that module versions that differ only in metadata are correctly de-duplicated by Fabric Loader at runtime, so that is no longer an issue.

My Proposed Solution

My proposed solution does not change the Fabric landscape much. Instead, it touches API and the example mod in small ways that make depending on API modules easier and should gradually phase out the need for players to download the full API.

Proposed Changes

  • Remove "fabric": "*" from example mod's fabric.mod.json
  • Remove fabric API dependency from example mod's build.gradle
  • Encourage mod devs to depend on and include the specific Fabric API modules they need
  • Add the Minecraft version API modules were built against to the module version metadata
  • Add configuration to the include directive to produce a flattened JIJ
    • Mods that include several libraries would not need to store duplicate JIJ dependencies.

Corresponding Issues and PRs

  • Loom issue #215
  • Fabric API PR #634
  • Fabric Example Mod issue #55

Benefits

I assume here that most mods depend on a small number of API modules. For example, my own mod Structure Helpers depends on only three API modules (Resource Loader, BE Networking, and Networking). The Luminiferous Uplands may be an example of an extensive content mod, and even it uses only 10 of the Fabric API's 30 modules (Resource Loader, Object Builders, Content Registries, Tool Tags, BE Networking, Dimension, Render Layers, Rendering Registry, Item Groups, and Container). Users should therefore see fewer unused modifications in standalone mods, and most mod devs should see smaller development environments.

Caveats

Every mod that includes assets or data requires Resource Loader. Additionally, every mod that adds content to the vanilla registries requires Registry Sync. I propose that the mods that require these modules include them anyway (even if almost every mod needs it). Modpack developers can handle de-duplication and the two API modules should be small enough not to impact download size much. An alternative is not to include these two modules and to require players to download these two modules separately. This second option is obviously more work for the player.

Alternative Solutions

Here, I examine a few of the proposed solutions and the disadvantages to them.

Add Fabic API module support to Loom (Loom PR #183)

This PR adds support into Loom to automatically fetch Fabric API modules specific to a Fabric API fat version. This solves the problem of determining which API modules to depend on, but it adds Fabric API specific behavior into Loom. Loom should not have to cater to the structure of the Fabric API.

Detect Unused Dependencies in Loom

This would automatically determine the (transitive) dependencies required in a mod and include them in the mod jar automatically. This means mod devs do not have to depend on specific API modules. However, it is non-trivial to determine whether a dependency is used or not, and there is no PR yet which adds this functionality.

Alert Players to Install Fabric API (Fabric Installer PR #38)

This sidesteps the development issue and instead attempts to educate players about the current system. This proposal often includes messages in Fabric Loader or the Fabric Installer telling players to install Fabric API. This is undesirable because it elevates Fabric API to special status in the view of the player, may cause the player to download Fabric API when it is not needed, and is a maintainance burden for the Fabric tooling that otherwise does not need to be aware of Fabric API.

@i509VCB
Copy link

i509VCB commented May 29, 2020

Remove "fabric": "*" from example mod's fabric.mod.json
Remove fabric API dependency from example mod's build.gradle

Personally, I think these should be the last steps, but I assume you meant them in no particular order. Makes no sense to remove them before we have a solution.

I'd say a few options should still be left in:

A gimme everything option, but it shouldn't be encouraged. Personally the all modules jar should still exist for users to download, such as the case where API updates to fix a bug but no mods release a fix. As a user, I don't want to download 30+ jars lol, so to reduce the pain.

Do consider quote 143 as you approach this:
image

@kvverti
Copy link
Author

kvverti commented May 29, 2020

True, the full Fabric API jar (with all modules included) is still useful for players, and will continue to be necessary for as long as mods do not include Fabric API modules. I consider this to be a somewhat separate concern from mod development, where devs should be able to easily pull in only those API modules that they need to use. Encouraging devs to just include the whole API sabotages Fabric API's goal of being modular by putting the modules as second class to the full API.

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