标签提供器

标签生成

继承 TagsProvider 并实现 #addTags,即可为模组生成标签。实现后,必须将提供者添加到 DataGenerator。

TagsProvider 的 tag 创建 TagAppender,可添加对象、嵌套标签和可选条目;可选条目不存在时在加载阶段跳过。

原创说明图,依据 Forge 1.21.x 官方文档 绘制。

// 在模组事件总线上
@SubscribeEvent
public void gatherData(GatherDataEvent event) {
  event.getGenerator().addProvider(
    event.includeServer(), // 仅在生成服务端数据时运行
    // 继承 net.minecraftforge.common.data.BlockTagsProvider
    output -> new MyBlockTagsProvider(output, event.getLookupProvider(), MOD_ID, event.getExistingFileHelper())
  );
}

TagsProvider

标签提供者有两种生成标签的方法:通过 #tag 使用对象和其他标签创建标签,或通过 #getOrCreateRawBuilder 使用其他对象类型的标签生成标签数据。

注意:通常无需直接调用 #getOrCreateRawBuilder,除非一个注册表包含另一个注册表中对象的表示,例如方块有物品形式,使其可在物品栏中获取。

调用 #tag 会创建 TagAppender,它是可链式调用的消费者,用于向标签添加元素:

方法 说明
add 通过资源键向标签添加对象。
addOptional 通过名称添加对象;对象不存在时加载时跳过。
addTag 通过标签键向标签添加另一个标签,内层标签的所有元素成为外层标签的一部分。
addOptionalTag 通过名称添加标签;标签不存在时加载时跳过。
replace 为 true 时丢弃其他数据包此前加入该标签的全部条目;此数据包之后加载的数据包仍会追加条目。
remove 通过名称或键从标签移除对象或标签。
// 在 TagProvider#addTags 中
this.tag(EXAMPLE_TAG)
  .add(EXAMPLE_OBJECT) // 向标签添加对象
  .addOptional(ResourceLocation.fromNamespaceAndPath("othermod", "other_object")); // 添加其他模组对象
this.tag(EXAMPLE_TAG_2)
  .addTag(EXAMPLE_TAG) // 向标签添加另一个标签
  .remove(EXAMPLE_OBJECT); // 从标签移除对象

重要:如果模组标签软依赖另一个模组的标签(运行时对方可能存在也可能不存在),应通过 optional 方法引用对方标签。

现有提供者

Minecraft 为某些注册表提供了可继承的标签提供者,部分提供者还有更方便创建标签的辅助方法。

注册对象类型 标签提供者
Block BlockTagsProvider(Forge 添加)
Item ItemTagsProvider
EntityType EntityTypeTagsProvider
Fluid FluidTagsProvider
GameEvent GameEventTagsProvider
Biome BiomeTagsProvider
FlatLevelGeneratorPreset FlatLevelGeneratorPresetTagsProvider
WorldPreset WorldPresetTagsProvider
Structure StructureTagsProvider
PoiType PoiTypeTagsProvider
BannerPattern BannerPatternTagsProvider
CatVariant CatVariantTagsProvider
PaintingVariant PaintingVariantTagsProvider
Instrument InstrumentTagsProvider
DamageType DamageTypeTagsProvider
ItemTagsProvider#copy

方块具有物品形式,因此许多方块标签也可以是物品标签。为了方便生成与方块标签具有相同条目的物品标签,可使用 #copy,传入来源方块标签和目标物品标签。

// 在 ItemTagsProvider#addTags 中
this.copy(EXAMPLE_BLOCK_TAG, EXAMPLE_ITEM_TAG);

自定义标签提供者

通过继承 TagsProvider 并传入要生成标签的注册表键,可创建自定义标签提供者。

public RecipeTypeTagsProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> registries, ExistingFileHelper fileHelper) {
  super(output, Registries.RECIPE_TYPE, registries, MOD_ID, fileHelper);
}

IntrinsicHolderTagsProvider

IntrinsicHolderTagsProvider 是特殊的标签提供者。通过它的 #tag 创建标签时,可以直接使用对象本身,通过 #add 将对象加入标签。为此,构造函数需提供一个将对象转换为其 ResourceKey 的函数。

// IntrinsicHolderTagsProvider 的子类型
public AttributeTagsProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> registries, ExistingFileHelper fileHelper) {
  super(output, ForgeRegistries.Keys.ATTRIBUTES, registries,
    attribute -> ForgeRegistries.ATTRIBUTES.getResourceKey(attribute).get(), MOD_ID, fileHelper);
}

原文:Tag Generation。