Compatibility
Minecraft: Java Edition
Platforms
Supported environments
Tags
Creators
Details
The tag system is awesome! It is night and day for configuration AND compatibility of mods. This mod was made to backport the tag system from 1.13.
This mod was coded and upgraded entirely from the ground up; There is NO VANILLA code in it at all. The name TagManager was in direct reference to the heart of the newer system, "net.minecraft.tags.TagManager.class". In addition to being upgraded, this mod is highly optimized and tested. Not just optimized for performance but for memory too.
In addition to Tags, the mod also adds Tables and Integer Tables. This mod also provides some useful original tags like "tagmanager:tin_ores" for example.
To specify an exact metadata in an entry, use "_:#".
Example: "minecraft:planks:2" is Birch Planks.
The tags use the exact same format as in newer versions. Please remember that many entries use different id values before The Flattening. There is an additional way to add optional entries. Along with the vanilla way, you can specify an "optional" list along with "values".
Tables allow a block/X to be converted into another block/X. This is useful for stuff like deepslate in 1.12.2 or evil variants of biomes. This mod does NOT add deepslate or any new blocks. Tables are made as a list with a "to" and a "from" property. There is also a "name" property which is visible in the code but unused; It is just there so code can find entries if they need to. By default, the name will match the property "to".
Example:
{
"values": [
{
"from": "minecraft:log",
"to": "projectazalea:stripped_log"
},
{
"from": "minecraft:log2",
"to": "projectazalea:stripped_log2"
},
{
"from": "projectazalea:bark",
"to": "projectazalea:stripped_bark"
},
{
"name": "projectazalea:newer_bark_blocks",
"from": "projectazalea:bark2",
"to": "projectazalea:stripped_bark2"
}
]
}
Integer Tables convert X into integers. This is useful for stuff like enchantment power levels or ore values. These tables are structured with a "key" and a "value" property.
Example:
{
"values": [
{
"key": "minecraft:magma_cream",
"value": 2
},
{
"key": "minecraft:blaze_powder",
"value": 3
},
{
"key": "minecraft:torch",
"value": 3
},
{
"key": "minecraft:magma",
"value": 4
},
{
"key": "minecraft:lava_bucket",
"value": 5
},
{
"key": "minecraft:blaze_rod",
"value": 12
}
]
}
The load order is:
1: running TagPrimeEvent
2: saving config/default/*.json
3: loading config/custom/*.json and config/default/*.json
Using /reload DOES WORK (Outside the development environment) so you don't have to restart mc every time you make a change!
DISCLAIMER
Alone, TagManager data does nothing.
FOR DEVELOPERS
Spoiler
Unlike newer Minecraft, tags are made by code; Data packs are not yet modable in this version. It would not refresh at the right time and the only mod file loading code is client sided.
To create a tag, you must make a field to hold the tag key. Unlike newer mc, when The Flattening happened, blocks and items are specified differently.
Block tag keys are: "TagKey<IBlockState>"
Item tag keys are: "TagKey<ItemStack>"
The field ends with a call of "TagManager.X.createKey(R)". 'X' is the registry to create the key for, like BLOCKS or ITEMS. 'R' is the resource location used as the tag id.
That field is the tag reference.
To add entries to your tag or an existing one, you must use the sub class of TagPrimeEvent for the registry. From there you check which tag is being loaded and add to the specifed tag. THIS 'if' STATEMENT IS VITAL.
For example:
public static final TagKey<IBlockState>ALLOWS_WEBBED_COBBLESTONE=TagManager.BLOCKS.createKey(new ResourceLocation("mysticalmobs","allows_webbed_cobblestone"));
public static final TagKey<IBlockState>BANE_OF_ARTHROPODS_EFFECTIVE=TagManager.BLOCKS.createKey(new ResourceLocation("mysticalmobs","bane_of_arthropods_effective"));
public static final TagKey<IBlockState>WEBBED_COBBLESTONE_REPLACEABLE=TagManager.BLOCKS.createKey(new ResourceLocation("mysticalmobs","webbed_cobblestone_replaceable"));
public static final TagKey<IBlockState>WEB_CLUSTER_REPLACEABLE=TagManager.BLOCKS.createKey(new ResourceLocation("mysticalmobs","web_cluster_replaceable"));
public static final TagKey<IBlockState>WEB_COCOON_REPLACEABLE=TagManager.BLOCKS.createKey(new ResourceLocation("mysticalmobs","web_cocoon_replaceable"));
@SubscribeEvent public void prime(BlockTagPrimeEvent event){
if(event.tag==BlockTags.BASE_STONE_OVERWORLD)event.required.add("mysticalmobs:webbed_cobblestone");
else if(event.tag==BlockTags.FLOWER_POTS)event.required.add("mysticalmobs:buttercup_flower_pot");
else if(event.tag==BlockTags.SMALL_FLOWERS)event.required.add("mysticalmobs:buttercup");
else if(event.tag==ALLOWS_WEBBED_COBBLESTONE)event.required.add("mysticalmobs:web_cocoon");
else if(event.tag==BANE_OF_ARTHROPODS_EFFECTIVE){
event.required.add("minecraft:monster_egg");
event.required.add("minecraft:web");
event.required.add("mysticalmobs:web");
event.required.add("mysticalmobs:web_cocoon");
event.required.add("mysticalmobs:webbed_cobblestone");
}
else if(event.tag==WEBBED_COBBLESTONE_REPLACEABLE){
event.required.add("minecraft:cobblestone");
event.required.add("minecraft:gravel");
event.required.add("minecraft:monster_egg:0");
event.required.add("minecraft:monster_egg:1");
event.required.add("minecraft:mossy_cobblestone");
event.required.add("minecraft:stone:0");
}
else if(event.tag==WEB_CLUSTER_REPLACEABLE){
event.required.add("minecraft:air");
event.required.add("mysticalmobs:web");
}
else if(event.tag==WEB_COCOON_REPLACEABLE)event.required.add("minecraft:web");
}
Tag holding classes MUST be referenced in FMLPreInitializationEvent or the game WILL CRASH!
For examples: MinecraftForge.EVENT_BUS.register(new ModBlockTags()); ...or... ModBlockTags.WEB_COCOON_REPLACEABLE.location();
To use a tag, you must call X.test(Y). 'X' is the instance of the tag key. 'Y' is the thing that needs to be tested.
This mod can be used as a soft dependancy for tags using only Java reflection. Here is a good way to do that:
import java.util.function.Predicate;
public static final Predicate<IBlockState>BASE_STONE_OVERWORLD;
public static final Predicate<IBlockState>EXAMPLE_BLOCK_TAG;
public static final Predicate<ItemStack>EXAMPLE_ITEM_TAG;
static{
Predicate<IBlockState>m,n;
Predicate<ItemStack>o;
try{
Method d=Class.forName("com.quethed.tagmanager.TagManager")
.getDeclaredMethod("createKey",ResourceLocation.class,ResourceLocation.class,BiConsumer.class);
ResourceLocation l=new ResourceLocation("minecraft","block");
m=(Predicate<IBlockState>)d.invoke(null,l,new ResourceLocation("minecraft","base_stone_overworld"),null);
n=(Predicate<IBlockState>)d.invoke(null,l,new ResourceLocation("mod","example"),new BiConsumer<ArrayList<String>,ArrayList<String>>(){
@Override public void accept(ArrayList<String>required,ArrayList<String>optional){
required.add("minecraft:carrots");
required.add("minecraft:potatoes");
optional.add("betternether:egg_plant");
}
});
o=(Predicate<ItemStack>)d.invoke(null,new ResourceLocation("minecraft","item"),new ResourceLocation("mod","example"),new BiConsumer<ArrayList<String>,ArrayList<String>>(){
@Override public void accept(ArrayList<String>required,ArrayList<String>optional){
required.add("minecraft:apple");
required.add("minecraft:carrot");
required.add("minecraft:potato");
optional.add("betternether:egg_plant");
}
});
}catch(Throwable e){
m=(a)->{
if(a.getBlock()!=Blocks.STONE)return false;
BlockStone.EnumType b=a.getValue(BlockStone.VARIANT);
return b==BlockStone.EnumType.STONE||b==BlockStone.EnumType.GRANITE||b==BlockStone.EnumType.DIORITE||b==BlockStone.EnumType.ANDESITE;
};
n=(a)->{
Block b=a.getBlock();
return b==Blocks.CARROTS||b==Blocks.POTATOES;
};
o=(a)->{
Item b=a.getItem();
return b==Items.APPLE||b==Items.CARROT||b==Items.POTATO;
};
}
BASE_STONE_OVERWORLD=m;
EXAMPLE_BLOCK_TAG=n;
EXAMPLE_ITEM_TAG=o;
}
Now that you know the basics of TagManager, please look at the code to learn more.
FOR USERS
Spoiler
Tags can be changed or read by modpack developers easily. There is no data pack support sadly. To change the data:
Step 1: find ":/config/tagmanager/default/T/R/N/P.json".
T = The type of data. R = The registry for T. N = The id of the mod. P = The name of the entry.
The defaults are NOT suitable for modification and WILL RESET every load. The default files are just there so you can see what the game is loading.
Step 2: Make a new json file in the same location but in "custom" instead of "default".
Step 3: Write the new data in the file. REMEMBER: ":/config/custom/" NOT ":/config/default/". The custom data will be mixed with the default unless "replace" is set to true.
FAQ:
Spoiler
Q: Can I share this...?
A: You can share the link or the non-comercial modpack. You may NOT repost this anywhere. This page is on Modrinth only to clarify. YOU CANNOT MAKE MONEY FROM MY MOD!
Q: Can I use this in my modpack?
A: You cannot use this in modpacks with any form of purchase around it, not even donation perks or locking behind paid servers for downloads.
Q: Can you please port to X version/mod loader?
A: I will only port to adjecient older versions. For newer versions, I am planning the data pack sequel, "TableManager". Basically, I will not make 1.10 until 1.11 is done.
Q: Can I use this in my video?
A: As long as you give me credit and link to this page. This page is on Modrinth only to clarify. The credit can be when it first appears only if used in a series. The link must be in all videos, the description is recommended for that.


