FabricMC / fabric

Essential hooks for modding with Fabric.
Apache License 2.0
2.33k stars 411 forks source link

[Suggestion]: Allow no-code mods to specify that their resources must apply after another mod #3543

Open TelepathicGrunt opened 9 months ago

TelepathicGrunt commented 9 months ago

My use case is I have some mod-compat datapack to add compatibility between my mods and other mods. Some of these datapacks require overriding datapack files within my original mod in order to work.

I was planning on turning these datapacks into datapacks-as-mods by adding just a fabric.mod.json file to them. No code what-so-ever. I can specify a dependency in that file but I do not see any way to specify that my datapack-as-mod should load its resources on top and override another mod.

Without this ordering being allowed, I cannot make these datapack-as-mods projects because it'll become random of whether the resources properly overrides or not and thus, the datapack mod could work some times and not work other times. Not ideal.

apple502j commented 9 months ago

3473 enforces internally (but not as an API guarantee) that resource packs are sorted alphabetically. We generally prefer using registerBuiltinResourcePack in this case, though.

TelepathicGrunt commented 9 months ago

So to achieve my goals with no code involved, I should make my datapack-as-mods have a modid that loads then after my main mod? That sounds cursed by I guess it is what it is

modmuss50 commented 8 months ago

It sounds like there are really two issues in one here:

As apple said registerBuiltinResourcePack is likely the way to go here, it doesnt seem to offer an API to specify the ordering thats possibly something we can discuss.

We dont really have a concept of no code mods, Im not really too sure this is something we want to go down as its likely a massive rabbit hole. I worry you would basicaly end up writing code in json. Having said that I do see the use case for datapacks as mods so im not tottaly against it.

lukebemish commented 8 months ago

Fabric already has no code mods tho - just don't specify any entrypoints. Generally speaking, no code mods in this context means either datapacks as mods or mods that contain only resources of some form that other mods read and do stuff with to provide features. There's not really anything missing there. The particular issue here is just providing a datapack in a mod, and making sure it's ordered properly

Jab125 commented 8 months ago

perhaps a custom field like forge that lets you show the mod as a resource/data pack explicitly

lukebemish commented 8 months ago

That isn't the real issue here - datapacks-as-mods, at least as being discussed here, already work fine - the issue in is that it's impossible to specify anything about the ordering of your mods built in datapack. I'm not really sure if there's a good way to solve that as those are currently ordered in mod load order, but given that datapack ordering can have effects that can't be easily dealt with, unlike mod initializer order, I feel like some solution is probably needed

TelepathicGrunt commented 8 months ago

What Luke said. The datapack-as-mod works perfectly fine in of itself. No issues there.

The issue is when you have a datapack mod that tries to override resources from another mod. Because Fabric doesn't allow for setting which mod's resource should load after another mod's, that makes it harder to have a datapack mod guarantee to always be applied overtop another mod.

apple502j commented 8 months ago

Fabric is a modding platform, not a datapack loading platform. I think it is easy enouh, though, for someone else to develop a mod which allows declaring registerBuiltinResourcePack packs in a JSON or something.

We could also add a way to include pack dependencies in that method. We have the necessary logics already. But exposing it in a declarative form seems like a job for another API.

TelepathicGrunt commented 8 months ago

Fabric is a modding platform, not a datapack loading platform.

If that was true, then datapack mods should not be loadable and require 1 entry point to always be specified.

apple502j commented 8 months ago

A mod without an entrypoint or a mixin is fine (e.g. JiJ modpack jar), and we don't add meaningless restrictions. It's not the intended usage, though, and if there's a simple solution that only requires you to write a dozen lines of code, then we suggest you use that.

TelepathicGrunt commented 8 months ago

The system I was trying to do was just have datapacks as small gradle projects that gets zipped up and posted to the sites. I didn't want any java code in these datapacks as I didn't want full fledge minecraft decompiling, coding, java compiling, etc just to make the Fabric jar. Just raw small datapacks in tiny gradle projects with just the mods.toml and fabric.mod.json files so either loader can pick it up. https://github.com/TelepathicGrunt/RepurposedStructuresCompatDatapacks/tree/main

Other datapackers might also want to repackage their datapacks as mods for easier user downloading and management with modpacks. And they may not know how to code. Feels unnecessary to force coding for this or forcing dependencies to a third party mod when Fabric API is extremely close to supporting this. Just needs some extra file or data in a file for specifying what mod loads after what that a mod can provide.

modmuss50 commented 8 months ago

Correct me if im wrong, but currently mods as datapacks have no order (non deterministic, but not random), I think it makes sense to have a way for certian datapacks to be loaded before or after other packs.

One solution is to allow certain mods to depend on others, thus go after them, doing this would add complexity and room for unfixable issues such as circular dependenies. This would also need to be seperate from loader and mod load order as a whole is something we try not to do in favour of providing a more localised solution.

Would it be a good idea to have 3 phases that a mod can load datapack content in? Such as:

Doing this for the entire mod's datapack might not be ideal, as you may want to have some content loaded in each phase. Vanilla already has high_contrast and programmer_art "sub packs" that solve a similar idea, in a way that doesnt need any code.

Fabric could support fabric_early and fabric_late subpacks, that are loaded before and after most modded content, this removes the need for any complex sorting and possible clashes, and would work easily for none code mods.

apple502j commented 8 months ago

One correction:

currently mods as datapacks have no order (non deterministic, but not random)

No, it is internally managed by TreeMap, so that would be sorted by mod ID, in alphabetical order (as noted above). We do have a unittest to verify this.

Also, pack dependency is totally a doable idea, the refactor was written to support that (we just need a way to specify the dependency). Circular dependency currently disables all packs that are circular, we could keep it that way or add them at the end, ordered alphabetically.

TelepathicGrunt commented 5 days ago

Just poking this. CurseForge seems to be making it difficult for some modpacks to redistribute my datapacks due to some rules they got going on if the pack uses a mod that loads datapacks outside of the resourcepacks folder.

I would like to switch to using a mod to package my Yung compat datapacks as a nicer workaround for modpacks to use. But this load order issue is still the roadblock for me. Currently, if I try to do it, the datapack working will be entirely dependent on load order of the mods rather than me specifying that the compat-datapack-as-mod should load its resources over top my Repurposed Structures mod.

lukebemish commented 5 days ago

I suppose an interim workaround would be to give it a higher mod ID alphabetically?

TelepathicGrunt commented 5 days ago

My concern with abusing the modid workaround for the compat mods is that if Fabric later changes how the order works, I blow up. I would be relying on undocumented internal behavior that can change at any time.

sfPlayer1 commented 4 days ago

The primary mod resource pack (the jar itself) loading definitely needs some control in the mod json, we could start with phases, maybe add within-phase mod id based constraints later?

modmuss50 commented 4 days ago

Please see: https://github.com/FabricMC/fabric/pull/4070 for this, it needs a bit of work on the tests but overall it seems like a solid approach. If you have any feedback please leave it on the PR.