Advancements
Advancements are tasks that can be achieved by the player which may advance the progress of the game. Advancements can trigger based on any action the player may be directly involved in.
All advancement implementations within vanilla are data driven via JSON. This means that a mod is not necessary to create a new advancement, only a data pack. A full list on how to create and put these advancements within the mod's resources can be found on the Minecraft Wiki. Additionally, advancements can be loaded conditionally and defaulted depending on what information is present (mod loaded, item exists, etc.).
Advancement Criteria
To unlock an advancement, the specified criteria must be met. Criteria are tracked through triggers which execute when a certain action is performed: killing an entity, changing an inventory, breading animals, etc. Any time an advancement is loaded into the game, the criteria defined are read and added as listeners to the trigger. Afterwards a trigger function is called (usually named #trigger) which checks all listeners as to whether the current state meets the conditions of the advancement criteria. The criteria listeners for the advancement are only removed once the advancement has been obtained by completing all requirements.
Requirements are defined as an array of string arrays representing the name of the criteria specified on the advancement. An advancement is completed once one string array of criteria has been met:
// In some advancement JSON
// List of defined criteria to meet
"criteria": {
"example_criterion1": { /*...*/ },
"example_criterion2": { /*...*/ },
"example_criterion3": { /*...*/ },
"example_criterion4": { /*...*/ }
},
// This advancement is only unlocked once
// - Criteria 1 AND 2 have been met
// OR
// - Criteria 3 and 4 have been met
"requirements": [
[
"example_criterion1",
"example_criterion2"
],
[
"example_criterion3",
"example_criterion4"
]
]
A list of criteria triggers defined by vanilla can be found in CriteriaTriggers. Additionally, the JSON formats are defined on the Minecraft Wiki.
Custom Criteria Triggers
Custom criteria triggers can be created by implementing SimpleCriterionTrigger for the created AbstractCriterionTriggerInstance subclass.
AbstractCriterionTriggerInstance Subclass
The AbstractCriterionTriggerInstance represents a single criteria defined in the criteria object. Trigger instances are responsible for holding the defined conditions, returning whether the inputs match the condition, and writing the instance to JSON for data generation.
Conditions are usually passed in through the constructor. The AbstractCriterionTriggerInstance super constructor requires the instance to define the registry name of the trigger and the conditions the player must meet as an ContextAwarePredicate. The registry name of the trigger should be supplied to the super directly while the conditions of the player should be a constructor parameter.
// Where ID is the registry name of the trigger
public ExampleTriggerInstance(ContextAwarePredicate player, ItemPredicate item) {
super(ID, player);
// Store the item condition that must be met
}
!!! note Typically, trigger instances have a static constructor which allow these instances to be easily created for data generation. These static factory methods can also be statically imported instead of the class itself.
```java
public static ExampleTriggerInstance instance(ContextAwarePredicate player, ItemPredicate item) {
return new ExampleTriggerInstance(player, item);
}
```
Additionally, the #serializeToJson method should be overridden. The method should add the conditions of the instance to the other JSON data.
@Override
public JsonObject serializeToJson(SerializationContext context) {
JsonObject obj = super.serializeToJson(context);
// Write conditions to json
return obj;
}
Finally, a method should be added which takes in the current data state and returns whether the user has met the necessary conditions. The conditions of the player are already checked through SimpleCriterionTrigger#trigger(ServerPlayer, Predicate). Most trigger instances call this method #matches.
// This method is unique for each instance and is as such not overridden
public boolean matches(ItemStack stack) {
// Since ItemPredicate matches a stack, a stack is the input
return this.item.matches(stack);
}
SimpleCriterionTrigger
The SimpleCriterionTrigger<T> subclass, where T is the type of the trigger instance, is responsible for specifying the registry name of the trigger, creating a trigger instance, and a method to check trigger instances and run attached listeners on success.
The registry name of the trigger is supplied to #getId. This should match the registry name supplied to the trigger instance.
A trigger instance is created via #createInstance. This method reads a criteria from JSON.
@Override
public ExampleTriggerInstance createInstance(JsonObject json, ContextAwarePredicate player, DeserializationContext context) {
// Read conditions from JSON: item
return new ExampleTriggerInstance(player, item);
}
Finally, a method is defined to check all trigger instances and run the listeners if their condition is met. This method takes in the ServerPlayer and whatever other data defined by the matching method in the AbstractCriterionTriggerInstance subclass. This method should internally call SimpleCriterionTrigger#trigger to properly handle checking all listeners. Most trigger instances call this method #trigger.
// This method is unique for each trigger and is as such not overridden
public void trigger(ServerPlayer player, ItemStack stack) {
this.trigger(player,
// The condition checker method within the AbstractCriterionTriggerInstance subclass
triggerInstance -> triggerInstance.matches(stack)
);
}
Afterwards, an instance should be registered using CriteriaTriggers#register during FMLCommonSetupEvent.
!!! important
CriteriaTriggers#register must be enqueued to the synchronous work queue via FMLCommonSetupEvent#enqueueWork as the method is not thread-safe.
Calling the Trigger
Whenever the action being checked is performed, the #trigger method defined by the SimpleCriterionTrigger subclass should be called.
// In some piece of code where the action is being performed
// Where EXAMPLE_CRITERIA_TRIGGER is the custom criteria trigger
public void performExampleAction(ServerPlayer player, ItemStack stack) {
// Run code to perform action
EXAMPLE_CRITERIA_TRIGGER.trigger(player, stack);
}
Advancement Rewards
When an advancement is completed, rewards may be given out. These can be a combination of experience points, loot tables, recipes for the recipe book, or a function executed as a creative player.
// In some advancement JSON
"rewards": {
"experience": 10,
"loot": [
"minecraft:example_loot_table",
"minecraft:example_loot_table2"
// ...
],
"recipes": [
"minecraft:example_recipe",
"minecraft:example_recipe2"
// ...
],
"function": "minecraft:example_function"
}
Conditionally-Loaded Data
There are times when modders may want to include data-driven objects using information from another mod without having to explicitly make that mod a dependency. Other cases may be to swap out certain objects with other modded entries when they are present. This can be done through the conditional subsystem.
Implementations
Currently, conditional loading is implemented for recipes and advancements. For any conditional recipe or advancement, a list of conditions to datum pair is loaded. If the conditions specified for a datum in the list is true, then that datum is returned. Otherwise, the datum is discarded.
{
// The type needs to be specified for recipes as they can have custom serializers
// Advancements do not need this type
"type": "forge:conditional",
"recipes": [ // Or 'advancements' for Advancements
{
// The conditions to check
"conditions": [
// Conditions in the list are ANDed together
{
// Condition 1
},
{
// Condition 2
}
],
"recipe": { // Or 'advancement' for Advancements
// The recipe to use if all conditions succeed
}
},
{
// Next condition to check if the previous fails
},
]
}
Conditionally-loaded data additionally have wrappers for data generation through ConditionalRecipe$Builder and ConditionalAdvancement$Builder.
Conditions
Conditions are specified by setting type to the name of the condition as specified by IConditionSerializer#getID.
True and False
Boolean conditions consist of no data and return the expected value of the condition. They are represented by forge:true and forge:false.
// For some condition
{
// Will always return true (or false for 'forge:false')
"type": "forge:true"
}
Not, And, and Or
Boolean operator conditions consist of the condition(s) being operated upon and apply the following logic. They are represented by forge:not, forge:and, and forge:or.
// For some condition
{
// Inverts the result of the stored condition
"type": "forge:not",
"value": {
// A condition
}
}
// For some condition
{
// ANDs the stored conditions together (or ORs for 'forge:or')
"type": "forge:and",
"values": [
{
// First condition
},
{
// Second condition to be ANDed (or ORed for 'forge:or')
}
]
}
Mod Loaded
ModLoadedCondition returns true whenever the specified mod with the given id is loaded in the current application. This is represented by forge:mod_loaded.
// For some condition
{
"type": "forge:mod_loaded",
// Returns true if 'examplemod' is loaded
"modid": "examplemod"
}
Item Exists
ItemExistsCondition returns true whenever the given item has been registered in the current application. This is represented by forge:item_exists.
// For some condition
{
"type": "forge:item_exists",
// Returns true if 'examplemod:example_item' has been registered
"item": "examplemod:example_item"
}
Tag Empty
TagEmptyCondition returns true whenever the given item tag has no items within it. This is represented by forge:tag_empty.
// For some condition
{
"type": "forge:tag_empty",
// Returns true if 'examplemod:example_tag' is an item tag with no entries
"tag": "examplemod:example_tag"
}
Creating Custom Conditions
Custom conditions can be created by implementing ICondition and its associated IConditionSerializer.
ICondition
Any condition only need to implement two methods:
| Method | Description |
|---|---|
| getID | The registry name of the condition. Must be equivalent to IConditionSerializer#getID. Used only for data generation. |
| test | Returns true if the condition has been satisfied. |
!!! note
Every #test has access to some IContext representing the state of the game. Currently, only tags can be obtained from a registry.
IConditionSerializer
Serializers need to implement three methods:
| Method | Description |
|---|---|
| getID | The registry name of the condition. Must be equivalent to ICondition#getID. |
| read | Reads the condition data from JSON. |
| write | Writes the given condition data to JSON. |
!!! note Condition serializers are not responsible for writing or reading the type of the serializer, similar to other serializer implementations in Minecraft.
Afterwards, a static instance should be declared to hold the initialized serializer and then registered using CraftingHelper#register either during the RegisterEvent for RecipeSerializers or during FMLCommonSetupEvent.
// In some serializer class
public static final ExampleConditionSerializer INSTANCE = new ExampleConditionSerializer();
// In some handler class
public void registerSerializers(RegisterEvent event) {
event.register(ForgeRegistries.Keys.RECIPE_SERIALIZERS,
helper -> CraftingHelper.register(INSTANCE)
);
}
!!! important
If using FMLCommonSetupEvent to register a condition serializer, it must be enqueued to the synchronous work queue via FMLCommonSetupEvent#enqueueWork as CraftingHelper#register is not thread-safe.
Global Loot Modifiers
Global Loot Modifiers are a data-driven method of handling modification of harvested drops without the need to overwrite dozens to hundreds of vanilla loot tables or to handle effects that would require interactions with another mod's loot tables without knowing what mods may be loaded. Global Loot Modifiers are also stacking, rather than last-load-wins, similar to tags.
Registering a Global Loot Modifier
You will need 4 things:
- Create a
global_loot_modifiers.json.- This will tell Forge about your modifiers and works similar to tags.
- A serialized json representing your modifier.
- This will contain all of the data about your modification and allows data packs to tweak your effect.
- A class that extends
IGlobalLootModifier.- The operational code that makes your modifier work. Most modders can extend
LootModifieras it supplies base functionality.
- The operational code that makes your modifier work. Most modders can extend
- Finally, a codec to encode and decode your operational class.
- This is registered as any other
IForgeRegistryEntry.
- This is registered as any other
The global_loot_modifiers.json
The global_loot_modifiers.json represents all loot modifiers to be loaded into the game. This file MUST be placed within data/forge/loot_modifiers/global_loot_modifiers.json.
!!! important
global_loot_modifiers.json will only be read in the forge namespace. The file will be neglected if it is under the mod's namespace.
entries is an ordered list of the modifiers that will be loaded. The ResourceLocations specified points to their associated entry within data/<namespace>/loot_modifiers/<path>.json. This is primarily relevant to data pack makers for resolving conflicts between modifiers from separate mods.
replace, when true, changes the behavior from appending loot modifiers to the global list to replacing the global list entries entirely. Modders will want to use false for compatibility with other mod implementations. Datapack makers may want to specify their overrides with true.
{
"replace": false, // Must be present
"entries": [
// Represents a loot modifier in 'data/examplemod/loot_modifiers/example_glm.json'
"examplemod:example_glm",
"examplemod:example_glm2"
// ...
]
}
The Serialized JSON
This file contains all of the potential variables related to your modifier, including the conditions that must be met prior to modifying any loot. Avoid hard-coded values wherever possible so that data pack makers can adjust balance if they wish to.
type represents the registry name of the codec used to read the associated JSON file. This must always be present.
conditions should represent the loot table conditions for this modifier to activate. Conditions should avoid being hardcoded to allow datapack creators as much flexibility to adjust the criteria. This must also be always present.
!!! important
Although conditions should represent what is needed for the modifier to activate, this is only the case if using the bundled Forge classes. If using LootModifier as a subclass, all conditions will be ANDed together and checked to see if the modifier should be applied.
Any additional properties read by the serializer and defined by the modifier can also be specified.
// Within data/examplemod/loot_modifiers/example_glm.json
{
"type": "examplemod:example_loot_modifier",
"conditions": [
// Normal loot table conditions
// ...
],
"prop1": "val1",
"prop2": 10,
"prop3": "minecraft:dirt"
}
IGlobalLootModifier
To supply the functionality a global loot modifier specifies, a IGlobalLootModifier implementation must be specified. These are instances generated each time a serializer decodes the information from JSON and supplies it into this object.
There are two methods that needs to be defined in order to create a new modifier: #apply and #codec. #apply takes in the current loot that will be generated along with the context information such as the currently level or additional defined parameters. It returns the list of drops to generate.
!!! note The returned list of drops from any one modifier is fed into other modifiers in the order they are registered. As such, modified loot can be modified by another loot modifier.
#codec returns the registered codec used to encode and decode the modifier to/from JSON.
The LootModifier Subclass
LootModifier is an abstract implementation of IGlobalLootModifier to provide the base functionality which most modders can easily extend and implement. This expands upon the existing interface by defining the #apply method to check the conditions to determine whether or not to modify the generated loot.
There are two things of note within the subclass implementation: the constructor which must take in an array of LootItemConditions and the #doApply method.
The array of LootItemConditions define the list of conditions that must be true before the loot can be modified. The supplied conditions are ANDed together, meaning that all conditions must be true.
The #doApply method works the same as the #apply method except that it only executes once all conditions return true.
public class ExampleModifier extends LootModifier {
public ExampleModifier(LootItemCondition[] conditionsIn, String prop1, int prop2, Item prop3) {
super(conditionsIn);
// Store the rest of the parameters
}
@NotNull
@Override
protected ObjectArrayList<ItemStack> doApply(ObjectArrayList<ItemStack> generatedLoot, LootContext context) {
// Modify the loot and return the new drops
}
@Override
public Codec<? extends IGlobalLootModifier> codec() {
// Return the codec used to encode and decode this modifier
}
}
The Loot Modifier Codec
The connector between the JSON and the IGlobalLootModifier instance is a Codec<T>, where T represents the type of the IGlobalLootModifier to use.
For ease of convenience, a loot conditions codec has been provided for an easy addition to a record-like codec via LootModifier#codecStart. This is utilized for data generation of the associated loot modifier.
// For some DeferredRegister<Codec<? extends IGlobalLootModifier>> REGISTRAR
public static final RegistryObject<Codec<ExampleModifier>> = REGISTRAR.register("example_codec", () ->
RecordCodecBuilder.create(
inst -> LootModifier.codecStart(inst).and(
inst.group(
Codec.STRING.fieldOf("prop1").forGetter(m -> m.prop1),
Codec.INT.fieldOf("prop2").forGetter(m -> m.prop2),
ForgeRegistries.ITEMS.getCodec().fieldOf("prop3").forGetter(m -> m.prop3)
)
).apply(inst, ExampleModifier::new)
)
);
Examples can be found on the Forge Git repository, including silk touch and smelting effects.
Datapacks
In 1.13, Mojang added datapacks to the base game. They allow for the modification of the files for logical servers through the data directory. This includes advancements, loot_tables, structures, recipes, tags, etc. Forge, and your mod, can also have datapacks. Any user can therefore modify all the recipes, loot tables, and other data defined within this directory.
Creating a Datapack
Datapacks are stored within the data directory within your project's resources.
Your mod can have multiple data domains, since you can add or modify already existing datapacks, like vanilla's, forge's, or another mod's.
You can then follow the steps found here to create any datapack.
Additional reading: Resource Locations
Loot Tables
Loot tables are logic files which dictate what should happen when various actions or scenarios occur. Although the vanilla system deals purely with item generation, the system can be expanded to perform any number of defined actions.
Data-Driven Tables
Most loot tables within vanilla are data driven via JSON. This means that a mod is not necessary to create a new loot table, only a Data pack. A full list on how to create and put these loot tables within the mod's resources folder can be found on the Minecraft Wiki.
Using a Loot Table
A loot table is referenced by its ResourceLocation which points to data/<namespace>/loot_tables/<path>.json. The LootTable associated with the reference can be obtained using LootDataResolver#getLootTable, where LootDataResolver can be obtained via MinecraftServer#getLootData.
A loot table is always generated with given parameters. The LootParams contains the level the table is generated in, luck for better generation, the LootContextParams which define scenario context, and any dynamic information that should occur on activation. The LootParams can be created using the constructor of the LootParams$Builder builder, and built via LootParams$Builder#create by passing in the LootContextParamSet.
A loot table may also have some context. The LootContext takes in the built LootParams and can set some random seeded instance. The context is created via the builder LootContext$Builder and built using LootContext$Builder#create by passing in a nullable ResourceLocation representing the random instance to use.
A LootTable can be used to generate ItemStacks using one of the available methods which may take in a LootParams or a LootContext:
| Method | Description |
|---|---|
getRandomItemsRaw |
Consumes the items generated by the loot table. |
getRandomItems |
Returns the items generated by the loot table. |
fill |
Fills a container with the generated loot table. |
!!! note
Loot tables were built for generating items, so the methods expect some handling for the ItemStacks.
Additional Features
Forge provides some additional behavior to loot tables for greater control of the system.
LootTableLoadEvent
LootTableLoadEvent is an event fired on the Forge event bus which is fired whenever a loot table is loaded. If the event is canceled, then an empty loot table will be loaded instead.
!!! important Do not modify a loot table's drops through this event. Those modifications should be done using global loot modifiers.
Loot Pool Names
Loot pools can be named using the name key. Any non-named loot pool will be the hash code of the pool prefixed by custom#.
// For some loot pool
{
"name": "example_pool", // Pool will be named 'example_pool'
"rolls": {
// ...
},
"entries": {
// ...
}
}
Looting Modifiers
Loot tables are now affected by the LootingLevelEvent, on the Forge event bus, in addition to the looting enchantment.
Additional Context Parameters
Forge extends certain parameter sets to account for missing contexts which may be applicable. LootContextParamSets#CHEST now allows for a LootContextParams#KILLER_ENTITY as chest minecarts are entities which can be broken (or 'killed'). LootContextParamSets#FISHING also allows for a LootContextParams#KILLER_ENTITY since the fishing hook is also an entity which is retracted (or 'killed') when the player retrieves it.
Multiple Items on Smelting
When using the SmeltItemFunction, a smelted recipe will now return the actual number of items from the result instead of a single smelted item (e.g. if a smelting recipe returns 3 items and there are 3 drops, then the result would be 9 smelted items instead of 3).
Loot Table Id Condition
Forge adds an additional LootItemCondition which allows certain items to generate for a specific table. This is typically used within global loot modifiers.
// In some loot pool or pool entry
{
"conditions": [
{
"condition": "forge:loot_table_id",
// Will apply when the loot table is for dirt
"loot_table_id": "minecraft:blocks/dirt"
}
]
}
Can Tool Perform Action Condition
Forge adds an additional LootItemCondition which checks whether the given LootContextParams#TOOL can perform the specified ToolAction.
// In some loot pool or pool entry
{
"conditions": [
{
"condition": "forge:can_tool_perform_action",
// Will apply when the tool can strip a log like an axe
"action": "axe_strip"
}
]
}
Tags
Tags are generalized sets of objects in the game used for grouping related things together and providing fast membership checks.
Finding Tags
When looking for existing tags, there's two main places to check:
Vanilla Tags
Vanilla tags are declared in the net.minecraft.tags package. For example, BlockTags contains all the Vanilla block tags, BiomeTags contains all the Vanilla biome tags, and so on.
Forge Tags
Forge bundles additional tags useful for mods, both Forge-specific and de-facto common tags that apply across all major mod loaders. You can find all of them in the net.minecraftforge.common.Tags class. The method names for each of the fields as well as code comment groups should make it clear which is a Forge-specific tag and which is a common tag.
!!! warning
The common c namespaced tags seen in Forge are common across all loaders, however other loaders may have additional loader-specific tags under the same c namespace. When making a multi-loader mod, it is recommended to check the tags for each loader to ensure compatibility if you are considering a c tag you saw on other loaders that is missing in Forge. Loader-specific c tags may be in Forge under the forge namespace until they become common across all loaders.
Full list of tags in Forge
You can find a full list of tags Forge adds on top of Vanilla Minecraft here.
Declaring Your Own Groupings
Tags are declared in your mod's datapack. For example, a TagKey<Block> with a given identifier of modid:foo/tagname will reference a tag at /data/<modid>/tags/blocks/foo/tagname.json. Tags for Blocks, Items, EntityTypes, Fluids, and GameEvents use the plural forms for their folder location while all other registries use the singular version (EntityType uses the folder entity_types while Potion would use the folder potion).
Similarly, you may append to or override tags declared in other domains, such as Vanilla, by declaring your own JSONs.
For example, to add your own mod's saplings to the Vanilla sapling tag, you would specify it in /data/minecraft/tags/blocks/saplings.json, and Vanilla will merge everything into one tag at reload, if the replace option is false.
If replace is true, then all entries before the json specifying replace will be removed.
Values listed that are not present will cause the tag to error unless the value is listed using an id string and required boolean set to false, as in the following example:
{
"replace": false,
"values": [
"minecraft:gold_ingot",
"mymod:my_ingot",
{
"id": "othermod:ingot_other",
"required": false
}
]
}
See the Vanilla wiki for a description of the base syntax.
There is also a Forge extension on the Vanilla syntax.
You may declare a remove array of the same format as the values array. Any values listed here will be removed from the tag. This acts as a finer grained version of the Vanilla replace option.
Using Tags In Code
Tags for all registries are automatically sent from the server to any remote clients on login and reload. Blocks, Items, EntityTypes, Fluids, and GameEvents are special cased as they have Holders allowing for available tags to be accessible through the object itself.
!!! note
Intrusive Holders may be removed in a future version of Minecraft. If they are, the below methods can be used instead to query the associated Holders.
ITagManager
Forge wrapped registries provide an additional helper for creating and managing tags through ITagManager which can be obtained via IForgeRegistry#tags. Tags can be created using using #createTagKey or #createOptionalTagKey. Tags or registry objects can also be checked for either or using #getTag or #getReverseTag respectively.
Custom Registries
Custom registries can create tags when constructing their DeferredRegister via #createTagKey or #createOptionalTagKey respectively. Their tags or registry objects can then checked for either using the IForgeRegistry obtained by calling DeferredRegister#makeRegistry.
Referencing Tags
There are four methods of creating a tag wrapper:
| Method | For |
|---|---|
*Tags#create |
BannerPattern, Biome, Block, CatVariant, DamageType, EntityType, FlatLevelGeneratorPreset, Fluid, GameEvent, Instrument, Item, PaintingVariant, PoiType, Structure, and WorldPreset where * represents one of these types. |
ITagManager#createTagKey |
Forge wrapped vanilla registries, registries can be obtained from ForgeRegistries. |
DeferredRegister#createTagKey |
Custom forge registries. |
TagKey#create |
Vanilla registries without forge wrappers, registries can be obtained from Registry. |
Registry objects can check their tags or registry objects either through their Holder or through ITag/IReverseTag for vanilla or forge registry objects respectively.
Vanilla registry objects can grab their associated holder using either Registry#getHolder or Registry#getHolderOrThrow and then compare if the registry object has a tag using Holder#is.
Forge registry objects can grab their tag definition using either ITagManager#getTag or ITagManager#getReverseTag and then compare if a registry object has a tag using ITag#contains or IReverseTag#containsTag respectively.
Tag-holding registry objects contain a method called #is in either their registry object or state-aware class to check whether the object belongs to a certain tag.
As an example:
public static final TagKey<Item> myItemTag = ItemTags.create(ResourceLocation.fromNamespaceAndPath("mymod", "myitemgroup"));
public static final TagKey<Potion> myPotionTag = ForgeRegistries.POTIONS.tags().createTagKey(ResourceLocation.fromNamespaceAndPath("mymod", "mypotiongroup"));
public static final TagKey<VillagerType> myVillagerTypeTag = TagKey.create(Registries.VILLAGER_TYPE, ResourceLocation.fromNamespaceAndPath("mymod", "myvillagertypegroup"));
// In some method:
ItemStack stack = /*...*/;
boolean isInItemGroup = stack.is(myItemTag);
Potion potion = /*...*/;
boolean isInPotionGroup = ForgeRegistries.POTIONS.tags().getTag(myPotionTag).contains(potion);
ResourceKey<VillagerType> villagerTypeKey = /*...*/;
boolean isInVillagerTypeGroup = BuiltInRegistries.VILLAGER_TYPE.getHolder(villagerTypeKey).map(holder -> holder.is(myVillagerTypeTag)).orElse(false);
Conventions
There are several conventions that will help facilitate compatibility in the ecosystem:
- If there is a Vanilla tag that fits your block or item, add it to that tag. See the list of Vanilla tags.
- If there is a Forge tag that fits your block or item, add it to that tag. The list of tags declared by Forge can be seen on GitHub.
- If there is a group of something you feel should be shared by the community, use the
forgenamespace instead of your mod id. - Tag naming conventions should follow Vanilla conventions. In particular, item and block groupings are plural instead of singular (e.g.
minecraft:logs,minecraft:saplings). - Item tags should be sorted into subdirectories according to their type (e.g.
forge:ingots/iron,forge:nuggets/brass, etc.).
Migration from OreDictionary
- For recipes, tags can be used directly in the vanilla recipe format (see below).
- For matching items in code, see the section above.
- If you are declaring a new type of item grouping, follow a couple naming conventions:
- Use
domain:type/material. When the name is a common one that all modders should adopt, use theforgedomain. - For example, brass ingots should be registered under the
forge:ingots/brasstag and cobalt nuggets under theforge:nuggets/cobalttag.
- Use
Using Tags in Recipes and Advancements
Tags are directly supported by Vanilla. See the respective Vanilla wiki pages for recipes and advancements for usage details.
Tags list
Forge bundles many tags useful for mods, both Forge-specific and de-facto common tags that apply across all major mod loaders. You can find all of them in the net.minecraftforge.common.Tags class. This page lists all those tags and their contents.
!!! note
This page does not include Vanilla tags. Refer to the net.minecraft.tags package for those.
This page is generated from the [CommonTagsDumper][commontagsdumper] and is correct as of Forge 52.0.20. Note that not all builds of Forge contain tag changes, so just because this page references an older build does not mean this page is outdated. However, you should treat the actual generated JSONs on the Forge GitHub repository found [here][tagsrepo] as the ground truth. This page is provided for convenience and is not guaranteed to be up-to-date.
block
c: common tags and forge: Forge-specific block tags, covering: barrels, barrels/wooden, bookshelves, budding_blocks, buds, chains, chests, chests/wooden, clusters, cobblestones, concretes, dyed (16 color sub-tags), glass_blocks (cheap / colorless / tinted), glass_panes (colorless), glazed_terracottas, obsidians (crying / normal), ores (netherite_scrap / quartz), player_workstations (crafting_tables / furnaces), sandstone (blocks / red_blocks / red_slabs / red_stairs / slabs / stairs / uncolored_blocks / uncolored_slabs / uncolored_stairs), skulls, stones, storage_blocks (per-material sub-tags), villager_job_sites, plus Forge-specific chests/ender, chests/trapped, cobblestone (deepslate / infested / mossy / normal), end_stones, fence_gates (wooden), fences (nether_brick / wooden), gravel, netherrack, ore_bearing_ground (deepslate / netherrack / stone), ore_rates (dense / singular / sparse), ores (coal / copper / diamond / emerald / gold / iron / lapis / redstone), ores_in_ground (deepslate / netherrack / stone), sand (colorless / red). c:hidden_from_recipe_viewers, c:relocation_not_supported, c:ropes, and forge:enderman_place_on_blacklist are empty tags (no members).
Representative members:
c:barrels:minecraft:barrelc:dyed/black:minecraft:black_banner,minecraft:black_bed,minecraft:black_concrete, etc.c:storage_blocks/iron:minecraft:iron_blockc:ores:minecraft:coal_ore,minecraft:iron_ore,minecraft:diamond_ore, etc.forge:chests/ender:minecraft:ender_chestforge:fences/wooden:minecraft:oak_fence,minecraft:acacia_fence, etc.
For the complete member lists, see the generated JSONs on the Forge GitHub repository or the Minecraft Wiki.
enchantment
c: enchantment tags grouped by effect: entity_auxiliary_movement_enhancements, entity_defense_enhancements, entity_speed_enhancements, increase_block_drops, increase_entity_drops, weapon_damage_enhancements.
c:entity_defense_enhancements:minecraft:protection,minecraft:blast_protection,minecraft:fire_protection, etc.c:entity_speed_enhancements:minecraft:depth_strider,minecraft:soul_speed,minecraft:swift_sneakc:increase_block_drops:minecraft:fortunec:increase_entity_drops:minecraft:lootingc:weapon_damage_enhancements:minecraft:sharpness,minecraft:smite,minecraft:bane_of_arthropods, etc.
For the complete member lists, see the generated JSONs on the Forge GitHub repository or the Minecraft Wiki.
entitytype
c:boats:minecraft:boat,minecraft:chest_boatc:bosses:minecraft:ender_dragon,minecraft:witherc:minecarts:minecraft:minecart,minecraft:chest_minecart,minecraft:tnt_minecart, etc.c:capturing_not_supported/c:teleporting_not_supported: empty tags (no members)
For the complete member lists, see the generated JSONs on the Forge GitHub repository or the Minecraft Wiki.
fluid
c:lava:minecraft:lava,minecraft:flowing_lavac:water:minecraft:water,minecraft:flowing_waterc:hidden_from_recipe_viewers/c:honey/c:milk: empty tags (no members)forge:potion/forge:gaseous/forge:beetroot_soup/forge:mushroom_stew/forge:rabbit_stew/forge:suspicious_stew: empty tags (no members)
For the complete member lists, see the generated JSONs on the Forge GitHub repository or the Minecraft Wiki.
item
c: common tags and forge: Forge-specific item tags, covering: animal_foods, armors, bricks (nether / normal), buckets (empty / entity_water / lava / milk / powder_snow / water), concrete_powders, concretes, crops (per-crop sub-tags), dusts (glowstone / redstone), dyed (16 color sub-tags), dyes (16 color sub-tags), enchantables, ender_pearls, fertilizers, foods (berry / bread / candy / cooked_fish / cooked_meat / cookie / edible_when_placed / food_poisoning / fruit / golden / raw_fish / raw_meat / soup / vegetable), gems (amethyst / diamond / emerald /
…(truncated)