For other mods

Twelve points are open, and nothing the mod ships is a special case it keeps for itself: every tier, module, cell, sort order and tooltip line goes through the same calls as yours.

The twelve points, and what each one adds
PointWhat it adds
registerTiera crate, with its block, its rows and its columns
registerModulea capacity module, pointed at an item tag
registerRowModulea module that buys rows, where the other buys stack size
registerModuleSlota cell on the tab, which grows with it
onTierRegistereda call for every tier registered after yours
CrateLayoutCallbackthe last word on rows per page and page count
CrateCapacityCallbackthe last word on what a slot holds, item by item
ConfigSchema.registerHolderyour own options, in the same settings file
ConfigBounds.registerGroupthe range each of them is pulled back into
registerSortOrdera sort button, with its icon and its comparator
CrateScreenCallbacka widget on the crate screen
CrateTooltipCallbacka line in a crate slot's tooltip

The entry point

DeepCrateAddon has two methods, which are two passes of the mod's start-up. onDeepCrateConfig() runs before the settings file is read, onDeepCrateInit() once the eleven shipped tiers are in place and before anything reads a registry. A module points at an item tag rather than at a precise item, so adding yours to deepcrate:module_512 makes it a module without a line of code.

A whole addon

Here is everything it takes to add a crate and a capacity module, with no mixin and nothing to ask for. The entry point is declared in your own fabric.mod.json:

fabric.mod.json"entrypoints": {
  "deepcrate": ["com.example.slatecrate.SlateCrateAddon"]
}

Your build script needs Fabric API and the DeepCrate jar on the same compile classpath, both through modImplementation rather than modRuntimeOnly: the events in the table above are Fabric Event objects that will not type-check without Fabric API, and reaching Blocks.register for a tier's block needs Fabric API's own access widener, so a runtime-only declaration fails before the addon even compiles.

build.gradle.ktsdependencies {
    modImplementation("net.fabricmc.fabric-api:fabric-api:0.141.4+1.21.11")
    modImplementation(files("libs/deepcrate-1.0.0.jar"))
}

That libs/ folder belongs to the addon's own project, next to its build script, and exists only so the code compiles: a player installs DeepCrate the ordinary way, the jar dropped into mods/ like any other mod.

Then the class itself. onDeepCrateInit() runs once the eleven shipped tiers are in place, before anything reads a registry:

SlateCrateAddon.javapackage com.example.slatecrate;

import net.minecraft.core.registries.Registries;
import net.minecraft.resources.Identifier;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
import oas.dreyka.deepcrate.api.CrateTier;
import oas.dreyka.deepcrate.api.DeepCrateAddon;
import oas.dreyka.deepcrate.api.DeepCrateApi;
import oas.dreyka.deepcrate.api.module.CrateModule;

public final class SlateCrateAddon implements DeepCrateAddon {
    private static final String NAMESPACE = "slatecrate";

    @Override
    public void onDeepCrateInit() {
        Identifier crate = Identifier.fromNamespaceAndPath(NAMESPACE, "slate_crate");
        DeepCrateApi.registerTier(new CrateTier(crate, 10, SlateCrateBlocks.SLATE_CRATE));

        Identifier module = Identifier.fromNamespaceAndPath(NAMESPACE, "module_1024");
        DeepCrateApi.registerModule(new CrateModule(module, 1024, TagKey.create(Registries.ITEM, module)));
    }
}

Ten rows of nine slots, and a module lifting every slot to 1024. The module points at an item tag carrying its own name, so any item added to slatecrate:module_1024 becomes that module with nothing more written. Adding yours to deepcrate:module_512 works the same way, and then asks for no Java at all.

What stays closed, and why

A tier stays Java. It carries a block, blocks enter the registry during mod loading, and that registry is frozen well before the first data file is read: a crate declared in JSON would arrive with nothing to stand on.

The layout event has the last word on pagination, but not on hiding rows. A layout whose pages do not cover the crate is refused, the even split takes over, and the reason is written to the log.

What bites first. The screen hands you a CrateScreenArea: the corner of the panel, its size, a way to add a widget, and keepClickable. Declare through that last one any rectangle drawn beyond the panel's edge, because the game counts a click outside a container screen as a click in the world, and releasing one there drops whatever the player is holding.

Where to report what breaks

The repository issues, github.com/Dreyka-Oas/DeepCrate/issues, the same address as the button at the foot of the home page. An entry point that moved without being announced is declared there like anything else, and the defects already known sit there open or closed in plain sight rather than in somebody's inbox.

A copper crate screen with a small button an addon hung at the bottom right, past the edge of the panel.
The button at the bottom right comes from an addon, hung through CrateScreenCallback.

The licence, for whoever reuses the code

The mod is under the MIT licence, not a closed one. Play it, share it, sell it, fork it and publish an addon built on it, all without asking permission first. Copy a piece of the code into another project and the one thing the licence requires travels with it: keep the copyright notice and the permission notice attached to that copy. It asks for nothing else, no credit in a README, no obligation to open the addon's own code. The full text sits in the repository's LICENSE file and in the license field of fabric.mod.json, and it is that text that governs rather than this page. Writing an addon against the twelve points above needs no permission at all: that is what they are for.