Fabric API

Fabric API

106M Downloads

Mod data packs load with lower priority than Vanilla data packs

LemmaEOF opened this issue · 22 comments

commented

Currently, mod data packs are added before the vanilla data pack is, resulting in them having a lower priority. This means that a mod can't use its data pack to override vanilla data like recipes. The insertion point for mod data packs should go after the insertion point for vanilla.

commented

While I agree with this in principle, it's sadly not that easy. The way that resource pack loading (and by extension data packs since they're 90% the same code) is designed, you have essentially two insertion points - bottom and top. The actual resulting order is processing order dependent, with each pack being inserted at the current bottom or top of the priority order as appropriate. Trying to reliably load Vanilla's resources before mod resources would require quite a bit of finegling due to this.

commented

Well as it is now, it's currently inserting all mod data packs with lower priority than vanilla's, at least according to the ordered list I get when I run /datapack list.

commented

Yes, because their insertion location is set to "bottom" and they're registered after Vanilla. In theory it could be as simple as registering them before Vanilla, but in practice that could cause a lot of potential issues.

commented

Yeah, that's fair. I might take a crack at it and see what I can do at some point.

commented

What would be functionally optimal would be to modify the Vanilla behavior so that the default data pack was always loaded first no matter what, and inserting at the bottom inserted just above Vanilla, but that breaks the core principle of preserving Vanilla behavior if just the loader and API are installed. Not entirely sure what / how much can be done here.

commented

well I mean one could argue that the current vanilla behavior is that the default data pack is always loaded first no matter what.

commented

That's only true in practice, not in implementation. The fact that there is an option to insert below Vanilla, even if it's currently unused, is something that needs to be preserved; otherwise, it'll cause problems if they ever do use it.

commented

Ah, that's a fair point. I'll take a look into what can be done; I might end up making a separate lib if needed.

commented

So after a bit of experimentation, I came up with this Mixin to make my data pack have higher priority than Vanilla's:

@Mixin(NamespaceResourceManager.class)
public abstract class NamespaceResourceManagerMixin {

    @Shadow @Final protected List<ResourcePack> packList;
    private ResourcePack capturedPack = null;
    private boolean hasVanillaGone = false;

    @Inject(method = "addPack", at = @At("HEAD"), cancellable = true)
    private void captureResourcePack(ResourcePack resourcePack_1, CallbackInfo ci) {
        if (resourcePack_1.getName().equals("Default")) {
            hasVanillaGone = true;
        }
        if (resourcePack_1.getName().equals("Nice to Have") && !hasVanillaGone) {
            capturedPack = resourcePack_1;
        }
    }

    @Inject(method = "addPack", at = @At(value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z", shift = At.Shift.AFTER))
    private void addCapturedPack(ResourcePack resourcePack_1, CallbackInfo ci) {
        if (hasVanillaGone && capturedPack != null) {
            NamespaceResourceManager self = ((NamespaceResourceManager)(Object)this);
            ResourcePack pack = capturedPack;
            packList.remove(capturedPack);
            capturedPack = null;
            self.addPack(pack);
        }
    }
}

This could easily be adapted to allow multiple resource packs to get captured. Additionally, a key in fabric.mod.json could indicate whether or not the modder wants their pack to be inserted below vanilla so that that option is preserved.

Note that the captured pack is removed from the list after the vanilla pack gets added otherwise the ModelManager can't find any mod models from the captured pack.

commented

Hm, that seems like it might be doable, since Fabric has a list of all the mod names. It doesn’t look like capturePackList needs to be cancellable.

commented

62841ce swaps using the insertion order from bottom to top which may be related. I assumed that it was the issue before fixing the other issue (since it was a discrepancy from Vanilla resource pack loading) but that may be causing unexpected behavior.

commented

Hm, that seems like it might be doable, since Fabric has a list of all the mod names. It doesn’t look like capturePackList needs to be cancellable.

Yeah, that was leftover from when I tried to cancel it to prevent duplication in the list...and is how I discovered that the ModelManager is really fussy about things.

Also, you wouldn't need the mod name since all mod resource & data packs are represented by the ModNioResourcePack, which contains its mod's metadata.

commented

Good news: My method does not cause #66 to occur.

commented

#66 was caused by the behavior of java's jar based resource functionality causing the Default pack to load mod resources which is entirely different from the issue here.

commented

sigh, I was saying that my solution to this issue did not cause the same problems as setting the insertion position to the bottom did.

commented

Yes, I understand. But what I was trying to say is that the the insertion order being BOTTOM may have actually been correct and that should be tested.

commented

Ah, my bad; I misread your comment.

commented

No problem, that was something that was an oversight with my work and I just wanted to make sure that it was properly investigated since what I did could be causing the issue!

commented

Would it just be a matter of swapping the insertion order back or does something in MixinDefaultResourcePack have to be changed as well?

commented

Just swapping the insertion order back is worth a shot, since it hasn't been specifically tested yet.

commented

Closing this issue as it was fixed a little while ago when the injections points of resource-loader were rewritten.

Tested again to make sure and modded datapacks take higher priority over the vanilla datapack.

commented

Not sure if this is an issue anymore? Testing is needed to validate this.