Registry Checklist

Pretty much everything in Forge needs to be registered: blocks, items, entities, and so on. This is how I create a new registry whenever I want to have a class handle a new object. I try to avoid creating globals when I do this, but other implementations may see more uses of the static keyword.

Checklist


  1. Construct the registry
  2. Create initialisation method
  3. Create accessors to registry objects
  4. Create and initialise it during mod construction

Construction


A basic registry needs a DeferredRegister for the type of object you want to register, as well as a constructor for that register. The register must also be itself registered with the Mod Event Bus.

A simple registry implementation might look like this:

public class BlockRegistry {

    // An instance of a deferred registry we use to register items.
    private final DeferredRegister<Block> deferredRegister;

    /**
     * Construction
     * @param modEventBus The event bus to register with.
     */
    public BlockRegistry(IEventBus modEventBus) {
        this.deferredRegister = DeferredRegister.create(ForgeRegistries.BLOCKS, ButterfliesMod.MOD_ID);
        this.deferredRegister.register(modEventBus);
    }
}

Initialisation


Registering new objects is done in an initialise method. A separate method is used to avoid circular dependencies on construction (e.g. Block Registries and Block Entity Registries need each other). If you are using static values and static initialisation, this method isn’t needed.

An example of a basic initialisation method is as follows:

    // Butterfly Feeder
    private RegistryObject<Block> butterflyFeeder;

    /**
     * Register the blocks.
     * @param blockEntityTypeRegistry The block entity registry.
     * @param menuTypeRegistry The menu type registry.
     */
    public void initialise(BlockEntityTypeRegistry blockEntityTypeRegistry,
                           MenuTypeRegistry menuTypeRegistry) {

        this.butterflyFeeder = deferredRegister.register( "butterfly_feeder",
                () -> new ButterflyFeederBlock(blockEntityTypeRegistry, menuTypeRegistry));
    }

Access


For any registered objects that need to be accessed outside of the registry, an accessor is needed. This also isn’t needed if you are using static initialisation and make all your RegistryObject instances publicly accessible.

    /**
     * Get the butterfly feeder block.
     * @return The butterfly feeder block.
     */
    public RegistryObject<Block> getButterflyFeeder() {
        return butterflyFeeder;
    }

Mod Construction


All registries should be created and initialised in the Mod constructor. First, create all registries, then initialise them. My current registry initialisation looks like this:

    /**
     * Constructor.
     */
    public ButterfliesMod() {
        final IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
        final IEventBus forgeEventBus = MinecraftForge.EVENT_BUS;

        // Create the registries.
        BlockEntityTypeRegistry blockEntityTypeRegistry = new BlockEntityTypeRegistry(modEventBus);
        BlockRegistry blockRegistry = new BlockRegistry(modEventBus);
        EntityTypeRegistry entityTypeRegistry = new EntityTypeRegistry(modEventBus);
        ItemRegistry itemRegistry = new ItemRegistry(modEventBus);
        LootModifierRegistry lootModifierRegistry = new LootModifierRegistry(modEventBus);
        MenuTypeRegistry menuTypeRegistry = new MenuTypeRegistry(modEventBus);
        PoiTypeRegistry poiTypesRegistry = new PoiTypeRegistry(modEventBus);
        VillagerProfessionRegistry villagerProfessionRegistry = new VillagerProfessionRegistry(modEventBus);

        // Initialise the registries. Do this here because (e.g.)
        // blockEntityTypeRegistry requires blockRegistry to be created and
        // vice-versa.
        blockEntityTypeRegistry.initialise(blockRegistry, menuTypeRegistry);
        blockRegistry.initialise(blockEntityTypeRegistry, menuTypeRegistry);
        entityTypeRegistry.initialise(blockRegistry);
        itemRegistry.initialise(blockRegistry, entityTypeRegistry);
        lootModifierRegistry.initialise(itemRegistry);
        menuTypeRegistry.initialise();
        poiTypesRegistry.initialise(blockRegistry);
        villagerProfessionRegistry.initialise(poiTypesRegistry);

        // Other initialisation stuff here.
    }