Fabric API

Fabric API

106M Downloads

Modularization plan of Fabric: Basic, Client, Server, Game

liach opened this issue ยท 13 comments

commented

Modularization plan of Fabric

History

Back in 2016, Fabric had a modularization plan, which it splits resources, network, registry, commands, etc. to different projects. This attempt did not see much success.

Current Situation

Now, fabric groups by mod loader and modding api components. We now have:

  • Loader
    • Injects mod loading hooks to a Java game.
    • No extra dependencies.
  • API (Fabric mod)
    • Exposes some frequently-used functionalities.
    • Depends on the Loader.
  • Kotlin support
    • Supports Kotlin mods.
    • Depends on the Loader.
  • Scala support
    • Supports Scala mods.
    • Depends on the Loader.

This setup appears to be more realistic than the previous one. However, this setup still has a hodgepodge of API content within a single module (Fabric mod, hence I opened the issue here)

Proposal

The Loader, Kotlin support, and Scala support parts will remain the same. The fabric mod will be split to these portions:

  • Base
    • Applicable to both the client and the dedicated server.
    • The modded client/server can connect to their vanilla counterparts.
    • Depends on the Loader.
    • Exemplary content: (Sorry, but I haven't thought of any yet)
  • Client
    • Applicable to clients only.
    • The modded client can connect to vanilla integrated/dedicated servers.
    • Depends on the Base (and the Loader).
    • Exemplary content: More keybinding, display tweaks, client render events, client-side hacks
    • Work like LiteLoader (open to discussion on whether to include integrated server content).
  • Server
    • Applicable to logical servers (integrated and dedicated servers).
    • The modded server can connect to vanilla clients.
    • Depends on the Base (and the Loader).
    • Exemplary content: Protocol modification on server side, worldedit, block/entity/item events, new advancement triggers, etc.
    • Work like SpongeAPI (applicable to both integrated and dedicated servers); content will be like Bukkit but can be on integrated server.
  • Game
    • Applicable to either client or the server.
    • The modded client/server has custom protocol and have block/item/entity registry differences, etc. that affect protocol.
    • Depends on the Client and the Server (also the Base and the Loader).
    • Exemplary content: New blocks, new items, new entities.
    • Work like most parts of the current Fabric and Forge.

Distribution

Even though we will have four modules, we will only have 3 distribution: the Client, the Server, and the Game.
Distribution plan
Client: Liteloader-like, for client-side aid mods installation/development, like autofish, dynamic lights, optifine, etc.
Server: Sponge/Bukkit-like, for server-side mods similar to forgeessentials, worldedit, and dynmap
Game: Big and true mods that add items, blocks, entities, etc. like TechRebornX, Towlette, more stairs, trapped shulker boxes, etc.

In my opinion, this setup can best serve these three groups of users/developers and make game load faster as well.

Reason

  1. Many gamer users only use "slight modification" (my invented term), in which they use client only mods to join some vanilla servers or servers with plugins (like spigot/bukkit servers or hypixel, etc.). These people can just use the Base + the Client in order to achieve their required functionalities instead of installing a heavy-weight mod API like the Game or Minecraft Forge.
  2. This increases Fabric's competitiveness as a server-side modding API on snapshot versions, where no Bukkit, Sponge, Spigot, or any of these alternatives publish a version. A setup like the Base + the Server resembles the so-called "NMS" used by plugins and can make it easier for plugin makers and snapshot server owners to get into Fabric.
  3. For novice modders, using correct dependencies for their mods would be able to let them do the right things. If a user want to write a plugin for server that accept vanilla clients and accidentally used hooks related to adding blocks, the user might never know why things get wrong as it would be hard to debug under an environment like existing Fabric API or pure Forge; however, if the user only uses the Base and the Server portions here, it would have a much lesser chance encountering such a hard-to-trace issue during development.
    • In general, this helps new modders understand the structure of Minecraft game as well.

Notes

This is not fully finished yet and is subject to modification and addition. However, I wish to hear your opinions on improvements for this model.

For integrated server, I desire to put it in server instead of client, as it would drastically increase client distribution size without offering much real benefit to client-only mods (like liteloader).

commented

From a programmer's perspective I like this setup.

How this structure is communicated to players and non-modders, though, will be what makes or breaks it.

  • how to explain the purpose of each module in plain English, and why they are split up this way at all?
  • how can modders easily communicate which modules their mod needs? (Create logos and other assets for modders to display? Rely on mod portals like Curse?) Mods will have a lot of dependencies.
  • how to answer the question "why not just put the Base content in the modloader itself, like Forge does, if every mod needs this content?"

(edit: the first 2 also apply to any other sort of modularization)

commented

We had been thinking of splitting the api into a few parts based on features.

One example would be a registry module, having this module installed in the game would most likely require the client to also have it installed and would allow for adding things to the registry, for example blocks and items.

There would then also be modules for commands for example, only mods that add commands would need to contain it, this would allow server side only mods to work as closely to vanilla as possible.

By splitting it up by features you end up with more modules, but then this allows for less changes to the game at run time. I can see this being a bit annoying for modders to keep track of what modules they would need to have enabled, this could possibly be solved by having clear docs on the modules that exist.

Or possibly the default modding workspace having access to all modules and then loom figures out what modules the modder wants? Could be a bit complex however.

I like your idea on the 4 different levels however some features might be hard to categorise or they might fit in 2 categories. For example the resource loading would fit in both the client and the server.

commented

This proposal doesn't make much sense, sorry. It doesn't really benefit anything and is really just a pretty pointless artificial modularization.

I think fabric should return to the mass modularity it used to have once we have jar in jar working. fabric-registry, fabric-resources, etc.

commented

That said, there may be room for additional fabric-client and fabric-server modules for specific things that clienside-only or severside-only modding would find useful.

commented

Back in 2016, Fabric had a modularization plan, which it splits resources, network, registry, commands, etc. to different projects. This attempt did not see much success.

we are waiting for loader 0.4 that enables jar in jar to "modularise" fabric as right now a user should not be expected to download 10 jars (they find 2 hard)

This setup appears to be more realistic than the previous one. However, this setup still has a hodgepodge of API content within a single module

If you look at the code here, https://github.com/FabricMC/fabric/tree/master/src/main/java/net/fabricmc/fabric/api they are very clearly set out, anything outside this api should not be used by a modder. This extends onto the mixins and the implementation of these apis.

This increases Fabric's competitiveness as a server-side modding API on snapshot versions

Right now this is tottaly possible, the modder just has to take care.

Other ideas:

Going on to the actual impl of this, gradle 5.3 includes a new thing called "feature variants".

Taken from the Gradle release page:

Often a library needs to express that some dependencies are only required if you use a specific feature of the library. Those dependencies must not be there unless you use that feature and therefore are often flagged as "optional" in Maven. This sounds like something loom could take use of to make the lives of modders easier.

commented

That said, there may be room for additional fabric-client and fabric-server modules for specific things that clienside-only or severside-only modding would find useful.

Modules would be marked if they could work server/client side only, Some basic client mod validation could slove some issues we are seeing right now.

commented

For @quat1024 #134 (comment):

  1. The purposes:
    1. Base: Common content between Client and Server to prevent duplicate code. Should not be offered standalone.
    2. Client: Needed for mods you use for joining plugin-servers (players know it; they play hypixel and spigot servers)
    3. Server: Needed for plugin servers (server owners know what they are running)
    4. Game: Needed for advanced modded games with "big mods".
  2. So to users, we can have a flow chart
    client server game
    Should be clear enough for users.
  3. Modders just need to indicate if they are making a client aid, a content mod, or a server plugin (server-only mod).
  4. For base content quat asked, we will not distribute it alone but will most likely include it with client/server together, much like how spongecommon works for spongeforge and spongevanilla.
commented

For @Prospector, you probably haven't played much hypixel or other plugin servers with client-only mods like minimaps. For those players, what they really need is just the client installation. You probably have not played with ForgeEssentials, dynmap, or FTBUtils that only requires installation on the logical server. As far as I see, you would just use the Game part, but that does not mean there is no one using the Client and the Server part.

In fact, there is even a case where both Client and Server would be used but the Game: the carpet mod by @Earthcomputer. It explores vanilla mechanisms so it needs both components but it does not all these advanced registry tools, etc.

commented

You can already use Fabric API on the clientside just fine though

commented

You can already use Fabric API on the clientside just fine though

Same goes for forge, but who wants to load all those energy api, inventory caps, and initialize obj model loader when you just want to add an autofish capability based on sound events

commented

The whole idea of jar in jar is that only the necessary components will load. With your proposal, everything on the clientside will load whether you need it or not.

commented

I like this proposal, and I would that add that Fabric and its distributions should consist only of these modules and each module should be as minimal as possible. All other APIs and extensions would be independent of the Fabric project itself - though I think our forums and wiki should help create visibility and feedback for development and adoption of external libraries.

This would mean things like #65 shouldn't even be part of Fabric - and I say that as the person who wrote that PR (with a lot of help). This is a change of heart for me, and merits some explanation:

Unlike Forge, Fabric does not have a full-time maintainer, and it seems unlikely it ever will. This is not meant as a slight to @asiekierka or @modmuss50 and other contributors who have done and continue to do more than anyone can reasonably expect to move the project forward. The point is that Fabric is already barely sustainable. A small handful of part-time contributors cannot maintain an ever-expanding scope and also meet the high bar that has been set by work already done.

The end result is that the project stalls. PRs languish or are never put forward. Mod authors cannot develop or release their content because they are waiting for that "one last thing" that has to happen before the thing they need. Therefore I would prefer to see the Fabric project focus on being a great toolchain and leave library development to the community.

Jar-in-Jar serves as an example. It's a nice feature that does belong in Fabric proper and I will make use of it when it gets here. But strictly speaking we don't need it to release content. And yet, much is waiting on it. That choice makes sense - and is arguable necessary - for the Fabric distribution itself. But it means everything that is or may be a part of the Fabric distribution is constrained by it.

Limiting Fabric's scope does necessarily mean we will have competing standards - at least until a consensus emerges - but that is already the case. We have an entire discord channel dedicated to debating configuration and still no official config API. If we're going to go that way, I say let mod authors with the interest publish their best effort and let the market decide.

I'll admit this isn't ideal, but it is practical. At least we will have solutions to choose from. And it's often good to have more than one option. Needs aren't all the same.

commented

Well, fabric has been modularized. I'd say this has been superseded