Fabric API

Fabric API

106M Downloads

FabricBlockLootTableProvider breaks depending on the mapping set

ChampionAsh5357 opened this issue ยท 1 comments

commented

This affects all Fabric APIs from Minecraft 1.19.3 onwards.

A Brief Background

FabricBlockLootTableProvider implements FabricLootTableProvider. FabricLootTableProvider extends a Consumer which is used to register the loot table entries to be written to the disk. The consumer itself is implemented within FabricBlockLootTableProvider#accept which implements the registration method.

@Override
public void accept(BiConsumer<Identifier, LootTable.Builder> biConsumer) {
generate();
for (Map.Entry<Identifier, LootTable.Builder> entry : lootTables.entrySet()) {
Identifier identifier = entry.getKey();
if (identifier.equals(LootTables.EMPTY)) {
continue;
}
biConsumer.accept(identifier, entry.getValue());
}
if (output.isStrictValidationEnabled()) {
Set<Identifier> missing = Sets.newHashSet();
for (Identifier blockId : Registries.BLOCK.getIds()) {
if (blockId.getNamespace().equals(output.getModId())) {
Identifier blockLootTableId = Registries.BLOCK.get(blockId).getLootTableId();
if (blockLootTableId.getNamespace().equals(output.getModId())) {
if (!lootTables.containsKey(blockLootTableId)) {
missing.add(blockId);
}
}
}
}
missing.removeAll(excludedFromStrictValidation);
if (!missing.isEmpty()) {
throw new IllegalStateException("Missing loot table(s) for %s".formatted(missing));
}
}
}

What is #accept?

It would be fine if #accept was just the name of the method passed into the Consumer. However, it is also the yarn mapping name for BlockLootTableGenerator#accept. In Yarn mappings, this is fine as #accept would then override Consumer#accept and implement perfectly. However, in other mapping sets, such as Mojmaps, the name is BlockLootSubProvider#generate. This requires a modder using Mojmaps to implement the #accept method from the Consumer and delegate to BlockLootSubProvider#generate.

This is an issue since it means that the code is reliant upon the mapping set. You need to add the method in non-Yarn mappings sets and remove the method in Yarn mapping sets, otherwise the call would infinitely recurse.

Possible Solution

Because of how Fabric implements loot table providers, the main solution would be to change FabricLootTableProvider to extend LootTableGenerator and call the associated method. This would prevent any disambiguation between mapping sets as the method's name would then change according to which mapping set it was apart of, rather than be static from the Consumer.

commented

See #3070 for a potential fix.