Difference between revisions of "Datageneration/Tags"

From Forge Community Wiki
(Update to 1.18.2)
(Finish tag providers)
 
Line 1: Line 1:
{{Under construction}}
+
Tags can be generated for a mod by subclassing <code>TagsProvider</code> and implementing <code>#addTags</code>. After implementation, the provider must be added to the <code>DataGenerator</code>.
  
Tags can be generated by extending the <code>ItemTagsProvider</code> for Items or <code>BlockTagsProvider</code> for Blocks. For Custom Objects you would need to expand <code>TagsProvider</code> and give it the Object you want tags for. For the registration of you Tags you need to override the <code>TagsProvider#addTags</code> method.
+
= TagsProvider =
  
 +
The tags provider typically generates tags via <code>#tag</code>.
  
{{Colored box|title=Information|content=You can still use <code>TagsProvider</code> for Items and Blocks but you would need to implement a lot of stuff that is already done in <code>ItemTagsProvider</code> and <code>BlockTagsProvider</code>}}
+
{{Tip|There is another method called <code>#getOrCreateRawBuilder</code>, but this is typically used only in cases when two registries represent the same object but in different forms (block and items).}}
  
==Items/Blocks==
+
When <code>#tag</code> is called, a builder is created to which the following methods can be chained:
First you should make a <code>TagKey</code> with <code>ItemTags#create</code> for Items or <code>BlockTags#create</code> for blocks, this will take the name of you Tag, see [[Tags#Conventions]]
 
for more info. After you have the <code>TagKey</code> you can start with the actual creation of the Tag, you would first call <code>TagsProvider#tag</code> which takes the tag as an argument, this returns a <code>TagsProvider$TagAppender</code>. Now you can with <code>TagsProvider$TagAppender#add</code> add one or more Items/Blocks or other Tags to your own Tags.
 
  
Example for an Item Tag:
+
{| class="wikitable sortable"
<syntaxhighlight lang="java">
+
! Method !! Description
TagKey<Item> copperTag = ItemTags.create(new ResourceLocation("forge", "ore/copper"));
+
|-
tag(copperTag).add(Init.COPPER_ORE_ITEM.get());
+
| <code>#add</code> || Adds an object to a tag.
</syntaxhighlight>
+
|-
 +
| <code>#addOptional</code> || Adds an object to a tag through its name. If the object is not present, then the object will be skipped when loading.
 +
|-
 +
| <code>#addTag</code> || Adds a tag to a tag. All elements within the inner tag are now a part of the outer tag.
 +
|-
 +
| <code>#addOptionalTag</code> || Adds a tag to a tag through its name. If the tag is not present, then the tag will be skipped when loading.
 +
|-
 +
| <code>#replace</code> || When <code>true</code>, all previously loaded entries added to this tag from other datapacks will be discarded. If a datapack is loaded after this one, then it will still append the entries to the tag.
 +
|-
 +
| <code>#remove</code> || Removes an object or all objects within a tag from a tag. If the object is not present in the tag, nothing happens.
 +
|}
  
 +
{{Tabs/Code Snippets|
 +
java=// In some TagProvider#addTags
 +
this.tag(EXAMPLE_TAG)
 +
  .add(EXAMPLE_OBJECT) // Adds an object to the tag
 +
  .addOptional(new ResourceLocation("othermod", "other_object")); // Adds an object from another mod to the tag
  
 +
this.tag(EXAMPLE_TAG_2)
 +
  .addTag(EXAMPLE_TAG) // Adds a tag to the tag
 +
  .remove(EXAMPLE_OBJECT); // Removes an object from this tag
 +
}}
  
==Custom Type for Tags==
+
{{Tip/Important|If the mod's tags softly depends on another mod's tags (the other mod may or may not be present at runtime), the other mods' tags should be referenced using the optional methods.}}
TBD
 
  
 +
== Using Existing Tag Providers ==
 +
 +
Vanilla contains a few tag providers for certain registries that can be subclassed for ease of implementation.
 +
 +
{| class="wikitable sortable"
 +
! Registry Object Type !! Tag Provider
 +
|-
 +
| <code>Block</code> || <code>BlockTagsProvider</code>
 +
|-
 +
| <code>Item</code> || <code>ItemTagsProvider</code>
 +
|-
 +
| <code>EntityType</code> || <code>EntityTypeTagsProvider</code>
 +
|-
 +
| <code>Fluid</code> || <code>FluidTagsProvider</code>
 +
|-
 +
| <code>GameEvent</code> || <code>GameEventTagsProvider</code>
 +
|-
 +
| <code>Biome</code> || <code>BiomeTagsProvider</code>
 +
|-
 +
| <code>FlatLevelGeneratorPreset</code> || <code>FlatLevelGeneratorPresetTagsProvider</code>
 +
|-
 +
| <code>WorldPreset</code> || <code>WorldPresetTagsProvider</code>
 +
|-
 +
| <code>Structure</code> || <code>StructureTagsProvider</code>
 +
|-
 +
| <code>PoiType</code> || <code>PoiTypeTagsProvider</code>
 +
|-
 +
| <code>BannerPattern</code> || <code>BannerPatternTagsProvider</code>
 +
|-
 +
| <code>CatVariant</code> || <code>CatVariantTagsProvider</code>
 +
|-
 +
| <code>PaintingVariant</code> || <code>PaintingVariantTagsProvider</code>
 +
|-
 +
| <code>Instrument</code> || <code>InstrumentTagsProvider</code>
 +
|}
 +
 +
{{Tabs/Code Snippets|
 +
java=public class ExampleBlockTagsProvider extends BlockTagsProvider {
 +
   
 +
    public ExampleBlockTagsProvider(DataGenerator gen, String modId, ExistingFileHelper efh) {
 +
        // ...
 +
    }
 +
 +
    @Override
 +
    public void addTags() {
 +
        // Add block tags here
 +
    }
 +
}
 +
}}
 +
 +
=== ItemTagsProvider#copy ===
 +
 +
Blocks have item representations such that they can be obtained within an inventory. As such, a number of block tags can also be applied to a similar item tag. To easily generate an item tag with the same entries as a block tag, the <code>#copy</code> method can be used.
 +
 +
{{Tabs/Code Snippets|
 +
java=// In #addTags within a ItemTagsProvider subclass
 +
this.copy(EXAMPLE_BLOCK_TAG, EXAMPLE_ITEM_TAG);
 +
}}
 +
 +
== Custom Tag Providers ==
 +
 +
A custom tag provider can be created via a <code>TagsProvider</code> subclass which takes in the <code>Registry</code> to generate tags for.
 +
 +
{{Tabs/Code Snippets|
 +
java=public RecipeTypeTagsProvider(DataGenerator gen, String modId, ExistingFileHelper efh) {
 +
  super(gen, Registry.RECIPE_TYPE, modId, efh);
 +
}
 +
}}
 +
 +
=== Forge Registry Tag Providers ===
 +
 +
If a registry is wrapped by Forge or created by a mod, a provider can be created via a <code>ForgeRegistryTagsProvider</code> subclass instead:
 +
 +
{{Tabs/Code Snippets|
 +
java=public AttributeTagsProvider(DataGenerator gen, String modId, ExistingFileHelper efh) {
 +
  super(gen, ForgeRegistries.ATTRIBUTES, modId, efh);
 +
}
 +
}}
  
 
[[Category:Data Generation]]
 
[[Category:Data Generation]]

Latest revision as of 22:12, 6 October 2022

Tags can be generated for a mod by subclassing TagsProvider and implementing #addTags. After implementation, the provider must be added to the DataGenerator.

TagsProvider

The tags provider typically generates tags via #tag.

There is another method called #getOrCreateRawBuilder, but this is typically used only in cases when two registries represent the same object but in different forms (block and items).

When #tag is called, a builder is created to which the following methods can be chained:

Method Description
#add Adds an object to a tag.
#addOptional Adds an object to a tag through its name. If the object is not present, then the object will be skipped when loading.
#addTag Adds a tag to a tag. All elements within the inner tag are now a part of the outer tag.
#addOptionalTag Adds a tag to a tag through its name. If the tag is not present, then the tag will be skipped when loading.
#replace When true, all previously loaded entries added to this tag from other datapacks will be discarded. If a datapack is loaded after this one, then it will still append the entries to the tag.
#remove Removes an object or all objects within a tag from a tag. If the object is not present in the tag, nothing happens.
// In some TagProvider#addTags
this.tag(EXAMPLE_TAG)
  .add(EXAMPLE_OBJECT) // Adds an object to the tag
  .addOptional(new ResourceLocation("othermod", "other_object")); // Adds an object from another mod to the tag

this.tag(EXAMPLE_TAG_2)
  .addTag(EXAMPLE_TAG) // Adds a tag to the tag
  .remove(EXAMPLE_OBJECT); // Removes an object from this tag


Important

If the mod's tags softly depends on another mod's tags (the other mod may or may not be present at runtime), the other mods' tags should be referenced using the optional methods.

Using Existing Tag Providers

Vanilla contains a few tag providers for certain registries that can be subclassed for ease of implementation.

Registry Object Type Tag Provider
Block BlockTagsProvider
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
public class ExampleBlockTagsProvider extends BlockTagsProvider {
    
    public ExampleBlockTagsProvider(DataGenerator gen, String modId, ExistingFileHelper efh) {
        // ...
    }

    @Override
    public void addTags() {
        // Add block tags here
    }
}


ItemTagsProvider#copy

Blocks have item representations such that they can be obtained within an inventory. As such, a number of block tags can also be applied to a similar item tag. To easily generate an item tag with the same entries as a block tag, the #copy method can be used.

// In #addTags within a ItemTagsProvider subclass
this.copy(EXAMPLE_BLOCK_TAG, EXAMPLE_ITEM_TAG);


Custom Tag Providers

A custom tag provider can be created via a TagsProvider subclass which takes in the Registry to generate tags for.

public RecipeTypeTagsProvider(DataGenerator gen, String modId, ExistingFileHelper efh) {
  super(gen, Registry.RECIPE_TYPE, modId, efh);
}


Forge Registry Tag Providers

If a registry is wrapped by Forge or created by a mod, a provider can be created via a ForgeRegistryTagsProvider subclass instead:

public AttributeTagsProvider(DataGenerator gen, String modId, ExistingFileHelper efh) {
  super(gen, ForgeRegistries.ATTRIBUTES, modId, efh);
}