Skip to content

Instantly share code, notes, and snippets.

@SizableShrimp
Last active January 20, 2023 04:19
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SizableShrimp/ddcbe9a9862cc4a0f526c42ae49b2c1d to your computer and use it in GitHub Desktop.
Save SizableShrimp/ddcbe9a9862cc4a0f526c42ae49b2c1d to your computer and use it in GitHub Desktop.
Overview of Forge 1.18.2 registry and tag changes

Overview of Forge 1.18.2 registry and tag changes

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.

Enabling tags for custom registries

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.

Tag file format for modded registries

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.

Changes to Entity Data Serializers, GLM Serializers, and Forge World Types

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_SERIALIZERS
  • ForgeRegistries.LOOT_MODIFIER_SERIALIZERS -> ForgeRegistries.Keys.LOOT_MODIFIER_SERIALIZERS
  • ForgeRegistries.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!

ITagManager system

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

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

DeferredRegister has seen no breaking changes but an expanded API and methods deprecated for removal.

Deprecated methods

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 the create method 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 the makeRegistry method that takes the super type Class instance.

New tag-related methods

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 the create method 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

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment