Forge version 1.18.2-40.0.18 introduced some changes to how custom registries and tags work to support Mojang's new universal tag system.
The differences between tags in 1.18.1 and 1.18.2 were great enough to warrant breaking changes in Forge where necessary.
For simplicity, custom Forge registries are opt-in for universal tags.
To enable tags for a registry, call RegistryBuilder#hasTags().
This tells Forge to run the necessary setup to allow tags for a custom registry.
Tag-enabled forge registries will be registered to the root registry in Registry to promote as much compatibility with vanilla systems as possible.
Modded tag-enabled registries have to use the format data/<namespace>/tags/<registrynamespace>/<registryname>/<tag>.json for tag JSON files.
This format is to prevent conflicts for registries with the same path but different namespaces.
For example, for a modded registry with the name examplemod:shoe and a tag with the key examplemod:blue_shoes, the full tag file path would be data/examplemod/tags/examplemod/shoe/blue_shoes.json.
The forge registries for DataSerializerEntry, GlobalLootModifierSerializer, and ForgeWorldPreset were all changed to deferred registers.
The fields in ForgeRegistries named DATA_SERIALIZERS, LOOT_MODIFIER_SERIALIZERS and WORLD_TYPES were all converted into suppliers.
If you make DeferredRegisters around these registries, you must use the Key now. See the following conversion list:
ForgeRegistries.DATA_SERIALIZERS->ForgeRegistries.Keys.DATA_SERIALIZERSForgeRegistries.LOOT_MODIFIER_SERIALIZERS->ForgeRegistries.Keys.LOOT_MODIFIER_SERIALIZERSForgeRegistries.WORLD_TYPES->ForgeRegistries.Keys.WORLD_TYPES
Full example: DeferredRegister.create(ForgeRegistries.Keys.LOOT_MODIFIER_SERIALIZERS, "modid");
If you need to query something from one of these 3 registries, call .get() on the fields in ForgeRegistries.
This will return null if called before the registries are created!
The ITagManager system is a completely new API that Forge provides for tag-enabled forge registries. This includes both vanilla and modded registries.
You can query an ITagManager system from a registry using IForgeRegistry#tags().
Each forge registry has its own ITagManager instance.
If a forge registry does not support tags, this will return null.
This class lets you lookup tags, create tags, create optional tags, and lookup a new concept called the reverse tag.
The system is pretty well documented in the code.
Please see the javadocs in your IDE for ITagManager, ITag, and IReverseTag for the most complete set of information.
ITag is a new class provided by the ITagManager system that represents a tag with a linked tag key and collection of values.
You can query an ITag using ITagManager#getTag.
This method will always return the same ITag instance for the same tag key from the same tag manager.
This means you can cache ITags across reloads for non-dynamic registries.
The concept of a reverse tag using IReverseTag is an object that is aware of what tags it is contained in.
All Holders implement this interface.
You can query an IReverseTag using ITagManager#getReverseTag by passing in a value registered to the associated forge registry.
The collection of tags that an object is contained in will be filled at the same time as normal tags.
Forge makes no guarantees about the lifetime of a reverse tag.
You should look up a reverse tag from its tag manager every time you need to query a value.
NewRegistry event has been entirely overhauled.
This event was moved from net.minecraftforge.event.RegistryEvent.NewRegistry to net.minecraftforge.registries.NewRegistryEvent.
All previous references to NewRegistry will be broken and need to be updated.
The event was moved to allow a smaller API within Forge.
If you were using NewRegistry to create custom registries, you must register your RegistryBuilders using NewRegistryEvent#create.
RegistryBuilder#create has been made private to allow Forge to have greater control over when your custom registries are created and configured.
Please note, you should be using DeferredRegisters as much as possible.
DeferredRegister has seen no breaking changes but an expanded API and methods deprecated for removal.
The following methods are deprecated for removal in 1.19:
DeferredRegister#create(Class, String)- DeferredRegisters no longer need to know the registry super type up front, instead taking the registry name. Please use thecreatemethod that takes a registry name instead.DeferredRegister#makeRegistry(String, Supplier<RegistryBuilder<T>>)- DeferredRegisters will require the super type when creating a registry in 1.19. Please use themakeRegistrymethod that takes the super typeClassinstance.
With the new tag system, DeferredRegisters now have new methods to let you create tag keys.
These should only be used if you are creating a custom modded registry.
Otherwise, please use the associated methods of the same name on ITagManager through IForgeRegistry#tags().
createTagKey- Creates a tag key for the DeferredRegister based on the registry name and provided String or ResourceLocation. If a String is provided, the currently set modid will be used as the tag namespace. You must be using thecreatemethod that takes a registry name.createOptionalTagKey- Creates a tag key with a set of default values if the tag does not exist. If a String is provided, the currently set modid will be used as the tag namespace. This is targeted towards client tags that may not exist on the server. Calling this multiple times will merge the defaults.addOptionalTagDefaults- Adds a set of default values to an existing tag key. Calling this multiple times will merge the defaults.
RegistryObject has seen no breaking changes but two methods deprecated for removal in 1.19 with RegistryObject#of(ResourceLocation, Supplier<Class<T>>) and RegistryObject#of(ResourceLocation, Class<T>).
Starting in 1.19, registries will no longer require uniqueness for super types.
This means that registry lookups based on class will no longer be supported in 1.19.
Please move to the of methods taking a forge registry, registry name, or registry key.