Skip to content

Registrum 核心 API 参考 >=1.21.1 26.1

AbstractRegistrum<S> 是注册引擎的基类。它为单个模组管理所有注册项、数据生成器、语言条目、创造模式选项卡以及事件监听器。 泛型参数 S 是自类型(例如 Registrum 继承自 AbstractRegistrum<Registrum>)。

本文档按功能分组,涵盖每一个公开方法。

有状态命名

object("name") 设置一个持久化名称,所有后续的构建器方法都会继承该名称,直到下一次调用 object() 为止。 或者,接受显式 String name 参数的方法则完全绕过当前名称状态。


静态方法与初始化

isDevEnvironment()

java
public static boolean isDevEnvironment()

当在非生产环境下运行时返回 true(即 FMLLoader#isProduction() == false)。 用于控制调试日志的详细程度以及跳过错误的资格。

java
if (AbstractRegistrum.isDevEnvironment()) {
    LOGGER.info("Running in development mode");
}

registerEventListeners(IEventBus)

java
public S registerEventListeners(IEventBus bus)

在构造期间调用,用于在模组事件总线上注册所有事件监听器。 订阅 RegisterEvent(常规 + LOWEST)、BuildCreativeModeTabContentsEventFMLCommonSetupEvent(清理)以及 GatherDataEvent.Client(仅数据生成)。

  • 如果尚未设置则设置 modEventBus
  • 使用 OneTimeEventReceiver 实现自动清理的监听器
  • 可重写以添加自定义监听器;务必调用 super
java
// 通常由 Registrum.create() 自动调用
Registrum reg = new Registrum("mymod");
reg.registerEventListeners(modEventBus);

object(String)

java
public S object(String name)

设置当前条目名称。之后所有省略显式 name 参数的构建器调用都将使用此值。 再次调用将覆盖之前的名称。

java
REGISTRUM.object("my_block")
    .block(MyBlock::new)       // 使用 "my_block"
    .register()
    .object("another_block")   // 切换名称
    .block(AnotherBlock::new); // 使用 "another_block"

skipErrors(boolean)

java
public S skipErrors(boolean skipErrors)

仅开发环境可用的开关。当设为 true 时,注册和数据生成期间的异常将被记录日志而非直接抛出,以便继续调试。

WARNING

skipErrors(true) 在非开发环境下会被静默忽略。

java
REGISTRUM.skipErrors(true).object("experimental")
    .block(ExperimentalBlock::new).register();

条目检索

用于获取之前已注册条目引用的方法。

方法签名描述
get(ResourceKey)<R,T> RegistryEntry<R,T> get(ResourceKey<? extends Registry<R>> type)按当前名称获取条目(需要先调用 object()
get(String, ResourceKey)<R,T> RegistryEntry<R,T> get(String name, ResourceKey<? extends Registry<R>> type)按显式名称获取条目
getOptional(String, ResourceKey)<R,T> Optional<RegistryEntry<R,T>> getOptional(String name, ResourceKey<? extends Registry<R>> type)获取可能不存在的条目
getAll(ResourceKey)<R,T> Collection<RegistryEntry<R,T>> getAll(ResourceKey<? extends Registry<R>> type)获取某个注册表的所有已知条目

参数:

参数类型描述
nameString条目名称(属于模组命名空间)
typeResourceKey<? extends Registry<R>>要查询的注册表(例如 Registries.BLOCK

返回类型:

方法返回值抛出异常
get(当前名称)RegistryEntry<R, T>若未设置 currentName 则抛出 NullPointerException
get(显式名称)RegistryEntry<R, T>若未找到注册项则抛出 IllegalArgumentException
getOptionalOptional<RegistryEntry<R, T>>无(若未找到则返回 Optional.empty()
getAllCollection<RegistryEntry<R, T>>
java
// 通过当前名称检索
RegistryEntry<Block, MyBlock> myBlock = REGISTRUM
    .object("my_block")
    .get(Registries.BLOCK);

// 通过显式名称检索(无需 object())
RegistryEntry<Item, BlockItem> item = REGISTRUM
    .get("my_block", Registries.ITEM);

// 安全的可选检索
Optional<RegistryEntry<Block, MyBlock>> opt = REGISTRUM
    .getOptional("missing_block", Registries.BLOCK);

// 获取所有已注册物品
Collection<RegistryEntry<Item, Item>> allItems = REGISTRUM
    .getAll(Registries.ITEM);

运行时可用性

get() / getOptional() / getAll() 返回的条目在 RegisterEvent 触发之前为空。 RegistryEntry 持有者本身即时有效,但其包裹的值在注册完成之前为 null


注册回调

在注册阶段期间和之后调用的回调。

addRegisterCallback(name, registryType, callback)

java
public <R, T extends R> S addRegisterCallback(
    String name,
    ResourceKey<? extends Registry<R>> registryType,
    NonNullConsumer<? super T> callback
)

添加一个在指定条目注册之后立即调用的回调。该回调会接收到已创建的条目对象。 如果条目已经注册,则回调会立即触发。

参数类型描述
nameString条目名称
registryTypeResourceKey<? extends Registry<R>>包含该条目的注册表
callbackNonNullConsumer<? super T>接收已注册对象的回调
java
REGISTRUM.addRegisterCallback("my_crop", Registries.BLOCK, block -> {
    ComposterBlock.COMPOSTABLES.put(block.asItem(), 0.65f);
});

addRegisterCallback(registryType, callback)

java
public <R> S addRegisterCallback(
    ResourceKey<? extends Registry<R>> registryType,
    Runnable callback
)

添加一个在整个注册表类型完成注册之后(在 LOWEST 优先级的 RegisterEvent 中)调用的回调。 在所有模组完成该类型的注册后触发。

参数类型描述
registryTypeResourceKey<? extends Registry<R>>要监听的注册表
callbackRunnable要调用的回调
java
REGISTRUM.addRegisterCallback(Registries.BLOCK, () -> {
    LOGGER.info("所有方块已注册完毕!");
});

isRegistered(ResourceKey)

java
public <R> boolean isRegistered(
    ResourceKey<? extends Registry<R>> registryType
)

检查某个注册表类型是否已完成注册。

java
if (REGISTRUM.isRegistered(Registries.BLOCK)) {
    // 可以安全地遍历所有方块
}

数据生成

数据生成器管理,仅在 GatherDataEvent 期间激活。

getDataProvider(GeneratorType)

java
public <P> Optional<P> getDataProvider(GeneratorType<P> type)

获取指定生成器类型的数据提供器实例。仅在数据生成阶段有效。

参数类型描述
typeGeneratorType<P>要获取的生成器类型
  • 返回:Optional<P> —— 对应的提供器,若本次数据生成运行中未注册则为空
  • 抛出:若在数据生成开始之前调用则抛出 IllegalStateException
java
// 在数据生成器回调内部
Optional<RegistrumBlockModelGenerator> modelGen = REGISTRUM
    .getDataProvider(ProviderType.BLOCK_MODEL);

setDataGenerator(Builder, GeneratorType, NonNullConsumer)

java
public <P, R> S setDataGenerator(
    Builder<R, ?, ?, ?> builder,
    GeneratorType<? extends P> type,
    NonNullConsumer<? extends P> cons
)

将数据生成器回调关联到特定的构建器条目。替换同一条目/类型组合上的任何现有回调。

java
// 通常通过 .setData() 在构建器链中调用
builder.setData(ProviderType.LOOT, (ctx, prov) -> {
    prov.addBlockLoot(ctx.getName());
});

setDataGenerator(String, ResourceKey, GeneratorType, NonNullConsumer)

java
public <P, R> S setDataGenerator(
    String entry,
    ResourceKey<? extends Registry<R>> registryType,
    GeneratorType<? extends P> type,
    NonNullConsumer<? extends P> cons
)

与上面相同,但通过名称和注册表类型而非构建器实例来标识条目。 这是构建器变体内部委托的实现。

addDataGenerator(GeneratorType, NonNullConsumer)

java
public <T> S addDataGenerator(
    GeneratorType<? extends T> type,
    NonNullConsumer<? extends T> cons
)

添加一个不与任何特定条目关联的数据生成器回调。用于杂项数据生成(全局配置、自定义 JSON 文件等)。 与 setDataGenerator 不同,此方法追加到现有回调之后。

参数类型描述
typeGeneratorType<? extends T>生成器类型
consNonNullConsumer<? extends T>消费该提供器的回调
java
REGISTRUM.addDataGenerator(ProviderType.LANG, lang -> {
    lang.add("mymod.greeting", "Hello World");
});

getDataGenInitializer()

java
public DataProviderInitializer getDataGenInitializer()

访问 DataProviderInitializer,用于配置提供器依赖关系和 datapack 注册表条目。 首次调用时延迟创建该初始化器。

java
REGISTRUM.getDataGenInitializer()
    .addDependency(ProviderType.BLOCK_TAGS, ProviderType.BLOCK_MODEL);

genData(GeneratorType, T)

java
public <T> void genData(GeneratorType<? extends T> type, T gen)

RegistrumDataProvider 调用的内部方法,用于执行给定提供器类型的所有已注册数据生成回调。 会同时调用与条目关联的回调和未关联的回调。

  • 错误会单独记录日志;若 skipErrorstrue,错误不会向上传播
  • 若数据生成未运行则为空操作

语言 / 翻译

所有三个方法都返回一个 MutableComponent(通过 Component.translatable(key)),适用于在 UI、提示框和创造模式选项卡标题中显示。 翻译值在数据生成期间通过 RegistrumLangProvider 写入。

addLang(type, id, localizedName)

java
public MutableComponent addLang(
    String type,
    Identifier id,
    String localizedName
)

使用原版风格的键生成方式(Util.makeDescriptionId)添加翻译。例如, ("block", "mymod:my_block", "My Block") 会生成键 "block.mymod.my_block"

参数类型描述
typeString键前缀(例如 "block""item""entity"
idIdentifier条目标识符
localizedNameString(英文)翻译值

addLang(type, id, suffix, localizedName)

java
public MutableComponent addLang(
    String type,
    Identifier id,
    String suffix,
    String localizedName
)

与上面相同,但追加一个以点号分隔的后缀。例如, ("block", id, "tooltip", "Hold shift for info") 会生成键 "block.mymod.my_block.tooltip"

addRawLang(key, value)

java
public MutableComponent addRawLang(String key, String value)

直接添加原始键值翻译对,绕过键生成逻辑。

java
// 原版风格(自动生成键)
MutableComponent name = REGISTRUM.addLang("block",
    Identifier.fromNamespaceAndPath("mymod", "my_block"),
    "My Special Block");

// 带后缀(用于提示框)
MutableComponent tooltip = REGISTRUM.addLang("block",
    Identifier.fromNamespaceAndPath("mymod", "my_block"),
    "tooltip", "A very special block");

// 原始键(自定义键)
MutableComponent custom = REGISTRUM.addRawLang(
    "mymod.custom.message", "Hello World");

创造模式选项卡(Resource Key)

这些方法控制默认的创造模式选项卡分配以及选项卡内容修改。

defaultCreativeTab(ResourceKey)

java
public S defaultCreativeTab(ResourceKey<CreativeModeTab> tab)

设置默认的创造模式选项卡。除非被覆盖,所有后续物品构建器将使用此选项卡。 初始默认为 CreativeModeTabs.SEARCH

java
REGISTRUM.defaultCreativeTab(CreativeModeTabs.BUILDING_BLOCKS);

defaultCreativeTab(RegistryEntry)

java
public S defaultCreativeTab(
    RegistryEntry<CreativeModeTab, CreativeModeTab> tab
)

便捷重载,从 RegistryEntry 中提取 ResourceKey。适用于由外部(非 Registrum)注册的创造模式选项卡。

modifyCreativeModeTab(ResourceKey, Consumer)

java
public S modifyCreativeModeTab(
    ResourceKey<CreativeModeTab> creativeModeTab,
    Consumer<CreativeModeTabModifier> modifier
)

注册一个在 BuildCreativeModeTabContentsEvent 期间调用的回调,用于修改特定创造模式选项卡的内容。 同一选项卡上的多个回调是叠加的。

参数类型描述
creativeModeTabResourceKey<CreativeModeTab>目标选项卡
modifierConsumer<CreativeModeTabModifier>接收一个用于添加物品的修改器的回调
java
REGISTRUM.modifyCreativeModeTab(CreativeModeTabs.BUILDING_BLOCKS, modifier -> {
    modifier.add(MY_BLOCK.get());
    modifier.addAfter(Items.STONE, MY_SPECIAL_BLOCK.get());
});

Transform

对 registrum 实例应用变换,或将流式链重定向到构建器辅助方法。

transform(NonNullUnaryOperator)

java
public S transform(NonNullUnaryOperator<S> func)

this 应用一个函数并返回结果。适用于配置 registrum 本身(而非转换到构建器)的辅助方法。

java
public static Registrum configureDefaults(Registrum r) {
    return r.defaultCreativeTab(CreativeModeTabs.BUILDING_BLOCKS);
}

REGISTRUM.transform(MyMod::configureDefaults)
    .object("my_block").block(MyBlock::new).register();

transform(NonNullFunction)

java
public <R, T extends R, P, S2 extends Builder<R, T, P, S2>> S2 transform(
    NonNullFunction<S, S2> func
)

应用一个返回 Builder 的函数,然后在该函数返回的对象上继续链式调用。 这是将构建器构造提取到辅助方法中的关键机制。

java
public static BlockBuilder<MyBlock, Registrum> createMyBlock(Registrum r) {
    return r.object("my_block").block(MyBlock::new);
}

REGISTRUM.transform(MyMod::createMyBlock)
    .lang("My Block")   // 链式调用在 BlockBuilder 上继续
    .simpleItem()
    .register();

自定义条目与注册表

entry(NonNullBiFunction)

java
public <R, T extends R, P, S2 extends Builder<R, T, P, S2>> S2 entry(
    NonNullBiFunction<String, BuilderCallback, S2> factory
)

使用工厂创建构建器,传入当前名称(来自 object())和一个 BuilderCallback。 这是自定义构建器类型的通用入口点。

entry(String, NonNullFunction)

java
public <R, T extends R, P, S2 extends Builder<R, T, P, S2>> S2 entry(
    String name,
    NonNullFunction<BuilderCallback, S2> factory
)

与上面相同,但使用显式名称,绕过当前名称状态。

java
// 使用当前名称
REGISTRUM.object("my_thing")
    .entry((name, callback) -> new MyCustomBuilder<>(
        REGISTRUM, REGISTRUM, name, callback));

// 使用显式名称
REGISTRUM.entry("my_thing", callback -> new MyCustomBuilder<>(
    REGISTRUM, REGISTRUM, "my_thing", callback));

makeRegistry(name, builder)

java
public <R> ResourceKey<Registry<R>> makeRegistry(
    String name,
    Function<ResourceKey<Registry<R>>, RegistryBuilder<R>> builder
)

通过 NewRegistryEvent 创建一个新的同步注册表。立即返回 ResourceKey; 实际的注册表稍后在事件触发时创建。

参数类型描述
nameString注册表 ID(属于模组命名空间)
builderFunction<ResourceKey, RegistryBuilder<R>>配置 RegistryBuilder 属性
java
ResourceKey<Registry<MyType>> MY_REGISTRY = REGISTRUM.makeRegistry(
    "my_custom",
    key -> new RegistryBuilder<MyType>(key)
        .sync(true)
        .maxId(256)
);

REGISTRUM.object("my_entry")
    .simple(MY_REGISTRY, MyType::new);

makeDatapackRegistry(name, codec)

java
public <R> ResourceKey<Registry<R>> makeDatapackRegistry(
    String name,
    Codec<R> codec
)

注册一个非同步的 datapack 注册表。数据 JSON 从 data/<datapack_namespace>/<modid>/<name>/ 加载。客户端不需要拥有此注册表即可连接到服务器。

makeDatapackRegistry(name, codec, networkCodec)

java
public <R> ResourceKey<Registry<R>> makeDatapackRegistry(
    String name,
    Codec<R> codec,
    @Nullable Codec<R> networkCodec
)

注册一个带有可选网络编解码器的 datapack 注册表。如果 networkCodec 非空, 数据将同步到客户端,且两侧都需要该注册表。

参数类型描述
nameString注册表 ID
codecCodec<R>用于从 datapack 加载数据的编解码器(服务端)
networkCodec@Nullable Codec<R>用于同步到客户端的编解码器;null = 非同步
java
// 非同步(仅服务端)
ResourceKey<Registry<MyData>> UNSYNCED = REGISTRUM.makeDatapackRegistry(
    "my_server_data", MyData.CODEC);

// 同步(客户端和服务端都需要)
ResourceKey<Registry<MyData>> SYNCED = REGISTRUM.makeDatapackRegistry(
    "my_synced_data", MyData.CODEC, MyData.NETWORK_CODEC);

通用注册(simple / generic)

simple() 立即返回一个 RegistryEntry(无构建器链)。generic() 返回一个 NoConfigBuilder,允许在最终完成之前调用 .lang().tag().register()

simple() 重载(4 个)

签名描述
simple(ResourceKey<Registry<R>>, NonNullSupplier<T>)当前名称,无父对象(self()
simple(String, ResourceKey<Registry<R>>, NonNullSupplier<T>)显式名称,无父对象
simple(P, ResourceKey<Registry<R>>, NonNullSupplier<T>)当前名称,指定父对象
simple(P, String, ResourceKey<Registry<R>>, NonNullSupplier<T>)显式名称,指定父对象
参数类型描述
registryTypeResourceKey<Registry<R>>目标注册表
factoryNonNullSupplier<T>条目构造器
nameString条目名称(可选)
parentP父对象(可选)
java
// 快速注册,无需构建器链
RegistryEntry<Item, MyItem> entry = REGISTRUM
    .object("my_item")
    .simple(Registries.ITEM, MyItem::new);

generic() 重载(4 个)

签名返回描述
generic(ResourceKey<Registry<R>>, NonNullSupplier<T>)NoConfigBuilder<R,T,S>当前名称,无父对象
generic(String, ResourceKey<Registry<R>>, NonNullSupplier<T>)NoConfigBuilder<R,T,S>显式名称,无父对象
generic(P, ResourceKey<Registry<R>>, NonNullSupplier<T>)NoConfigBuilder<R,T,P>当前名称,指定父对象
generic(P, String, ResourceKey<Registry<R>>, NonNullSupplier<T>)NoConfigBuilder<R,T,P>显式名称,指定父对象
java
// 适用于任意注册表类型的构建器链
REGISTRUM.object("my_entry")
    .generic(Registries.ITEM, MyItem::new)
        .lang("My Custom Item")
        .tag(ItemTags.SWORDS)
        .register();

Item 构建器(4 个重载)

创建一个 ItemBuilder。工厂函数接收 Item.Properties 并返回 Item 子类型。

签名名称来源父对象
item(NonNullFunction<Item.Properties, T>)currentName()S(registrum)
item(String, NonNullFunction<Item.Properties, T>)显式S(registrum)
item(P, NonNullFunction<Item.Properties, T>)currentName()P
item(P, String, NonNullFunction<Item.Properties, T>)显式P
参数类型描述
nameString条目名称(可选)
parentP构建器链中的父对象(可选)
factoryNonNullFunction<Item.Properties, T>从属性构造物品的工厂函数
java
REGISTRUM.object("my_item")
    .item(MyItem::new)              // 使用 currentName,父对象=self
    .tab(CreativeModeTabs.TOOLS)
    .lang("My Item")
    .register();

// 显式名称,无需 object()
REGISTRUM.item("another_item", MyItem::new)
    .tab(CreativeModeTabs.BUILDING_BLOCKS)
    .register();

默认创造模式选项卡

S 为父对象的 item() 重载会自动将 defaultCreativeTab(如果已设置)应用到构建器上。 以 P 为父对象的重载不会应用默认选项卡。


Block 构建器(4 个重载)

创建一个 BlockBuilder。工厂函数接收 BlockBehaviour.Properties 并返回 Block 子类型。

签名名称来源父对象
block(NonNullFunction<BlockBehaviour.Properties, T>)currentName()S
block(String, NonNullFunction<BlockBehaviour.Properties, T>)显式S
block(P, NonNullFunction<BlockBehaviour.Properties, T>)currentName()P
block(P, String, NonNullFunction<BlockBehaviour.Properties, T>)显式P
java
REGISTRUM.object("my_block")
    .block(MyBlock::new)
    .properties(p -> p.strength(3.0f).requiresCorrectToolForDrops())
    .simpleItem()                     // 自动创建 BlockItem
    .lang("My Block")
    .register();

Entity 构建器(4 个重载)

创建一个 EntityBuilder。接收 EntityFactory<T>MobCategory 分类。

签名名称来源父对象
entity(EntityFactory<T>, MobCategory)currentName()S
entity(String, EntityFactory<T>, MobCategory)显式S
entity(P, EntityFactory<T>, MobCategory)currentName()P
entity(P, String, EntityFactory<T>, MobCategory)显式P
参数类型描述
nameString条目名称(可选)
parentP父对象(可选)
factoryEntityFactory<T>(EntityType<T>, Level) -> T
classificationMobCategory生成分类(例如 MobCategory.CREATURE
java
REGISTRUM.object("my_entity")
    .entity(MyEntity::new, MobCategory.CREATURE)
    .renderer(() -> ctx -> new MyEntityRenderer(ctx))
    .attributes(MyEntity::createAttributes)
    .lang("My Entity")
    .register();

BlockEntity 构建器(4 个重载)

创建一个 BlockEntityBuilder。接收 BlockEntityFactory<T>

签名名称来源父对象
blockEntity(BlockEntityFactory<T>)currentName()S
blockEntity(String, BlockEntityFactory<T>)显式S
blockEntity(P, BlockEntityFactory<T>)currentName()P
blockEntity(P, String, BlockEntityFactory<T>)显式P
参数类型描述
nameString条目名称(可选)
parentP构建器链中的父对象(可选)
factoryBlockEntityFactory<T>(BlockEntityType<T>, BlockPos, BlockState) -> T
java
REGISTRUM.object("my_block")
    .block(MyBlock::new)
    .blockEntity(MyBlockEntity::new) // 使用 currentName "my_block"
        .renderer(() -> ctx -> new MyBlockEntityRenderer(ctx))
        .build()
    .register();

Fluid 构建器(36 个重载)

Fluid 重载按参数模式组织。每种模式最多有 4 种变体: 当前名称(无名称参数)、显式名称(String 参数)、父对象(父对象参数, 当前名称)以及父对象 + 名称(同时有父对象和显式名称)。

默认纹理

当省略静止/流动纹理时,Registrum 会自动生成 "block/<currentName>_still""block/<currentName>_flow"。传入显式的 Identifier 可进行覆盖。

基础 Fluid(无工厂,无自定义 FluidType)

签名返回说明
fluid()FluidBuilder<BaseFlowingFluid.Flowing, S>当前名称,默认使用 FluidType::new
fluid(String name)FluidBuilder<BaseFlowingFluid.Flowing, S>显式名称
fluid(P parent)FluidBuilder<BaseFlowingFluid.Flowing, P>父对象,currentName(),自动纹理
fluid(P parent, String name)FluidBuilder<BaseFlowingFluid.Flowing, P>父对象 + 名称,自动纹理
java
REGISTRUM.object("my_fluid")
    .fluid()                         // 默认 FluidType,自动纹理
    .lang("My Fluid")
    .register();

带 FluidTypeFactory

签名返回
fluid(FluidBuilder.FluidTypeFactory)FluidBuilder<BaseFlowingFluid.Flowing, S>
fluid(String, FluidBuilder.FluidTypeFactory)FluidBuilder<BaseFlowingFluid.Flowing, S>
fluid(P, FluidBuilder.FluidTypeFactory)FluidBuilder<BaseFlowingFluid.Flowing, P>
fluid(P, String, FluidBuilder.FluidTypeFactory)FluidBuilder<BaseFlowingFluid.Flowing, P>
java
REGISTRUM.object("my_fluid")
    .fluid(props -> props.temperature(300).viscosity(1000))
    .register();

带 NonNullSupplier<FluidType>

签名返回
fluid(NonNullSupplier<FluidType>)FluidBuilder<BaseFlowingFluid.Flowing, S>
fluid(String, NonNullSupplier<FluidType>)FluidBuilder<BaseFlowingFluid.Flowing, S>
fluid(P, NonNullSupplier<FluidType>)FluidBuilder<BaseFlowingFluid.Flowing, P>
fluid(P, String, NonNullSupplier<FluidType>)FluidBuilder<BaseFlowingFluid.Flowing, P>

带静止/流动纹理

签名返回
fluid(Identifier still, Identifier flowing)FluidBuilder<BaseFlowingFluid.Flowing, S>
fluid(String, Identifier, Identifier)FluidBuilder<BaseFlowingFluid.Flowing, S>
fluid(P, Identifier, Identifier)FluidBuilder<BaseFlowingFluid.Flowing, P>
fluid(P, String, Identifier, Identifier)FluidBuilder<BaseFlowingFluid.Flowing, P>

带纹理 + FluidTypeFactory

签名返回
fluid(Identifier, Identifier, FluidBuilder.FluidTypeFactory)FluidBuilder<BaseFlowingFluid.Flowing, S>
fluid(String, Identifier, Identifier, FluidBuilder.FluidTypeFactory)FluidBuilder<BaseFlowingFluid.Flowing, S>
fluid(P, Identifier, Identifier, FluidBuilder.FluidTypeFactory)FluidBuilder<BaseFlowingFluid.Flowing, P>
fluid(P, String, Identifier, Identifier, FluidBuilder.FluidTypeFactory)FluidBuilder<BaseFlowingFluid.Flowing, P>

带纹理 + NonNullSupplier<FluidType>

签名返回
fluid(Identifier, Identifier, NonNullSupplier<FluidType>)FluidBuilder<BaseFlowingFluid.Flowing, S>
fluid(String, Identifier, Identifier, NonNullSupplier<FluidType>)FluidBuilder<BaseFlowingFluid.Flowing, S>
fluid(P, Identifier, Identifier, NonNullSupplier<FluidType>)FluidBuilder<BaseFlowingFluid.Flowing, P>
fluid(P, String, Identifier, Identifier, NonNullSupplier<FluidType>)FluidBuilder<BaseFlowingFluid.Flowing, P>

带自定义 FluidFactory(泛型流体类型)

签名返回
fluid(Identifier, Identifier, FluidBuilder.FluidFactory<T>)FluidBuilder<T, S>
fluid(String, Identifier, Identifier, FluidBuilder.FluidFactory<T>)FluidBuilder<T, S>
fluid(P, Identifier, Identifier, FluidBuilder.FluidFactory<T>)FluidBuilder<T, P>
fluid(P, String, Identifier, Identifier, FluidBuilder.FluidFactory<T>)FluidBuilder<T, P>

带自定义 FluidFactory + FluidTypeFactory

签名返回
fluid(Identifier, Identifier, FluidBuilder.FluidTypeFactory, FluidBuilder.FluidFactory<T>)FluidBuilder<T, S>
fluid(String, Identifier, Identifier, FluidBuilder.FluidTypeFactory, FluidBuilder.FluidFactory<T>)FluidBuilder<T, S>
fluid(P, Identifier, Identifier, FluidBuilder.FluidTypeFactory, FluidBuilder.FluidFactory<T>)FluidBuilder<T, P>
fluid(P, String, Identifier, Identifier, FluidBuilder.FluidTypeFactory, FluidBuilder.FluidFactory<T>)FluidBuilder<T, P>

带自定义 FluidFactory + NonNullSupplier<FluidType>

签名返回
fluid(Identifier, Identifier, NonNullSupplier<FluidType>, FluidBuilder.FluidFactory<T>)FluidBuilder<T, S>
fluid(String, Identifier, Identifier, NonNullSupplier<FluidType>, FluidBuilder.FluidFactory<T>)FluidBuilder<T, S>
fluid(P, Identifier, Identifier, NonNullSupplier<FluidType>, FluidBuilder.FluidFactory<T>)FluidBuilder<T, P>
fluid(P, String, Identifier, Identifier, NonNullSupplier<FluidType>, FluidBuilder.FluidFactory<T>)FluidBuilder<T, P>
java
Identifier still = Identifier.fromNamespaceAndPath("mymod", "block/my_fluid_still");
Identifier flow  = Identifier.fromNamespaceAndPath("mymod", "block/my_fluid_flow");

// 自定义 FluidType + 自定义 FluidFactory
REGISTRUM.object("my_fluid")
    .fluid(still, flow,
        props -> new MyFluidType(props),
        MyFlowingFluid::new)
    .lang("My Fluid")
    .bucket()
    .register();

创建一个 MenuBuilder。同时支持标准 MenuFactory 和 Forge 扩展的 ForgeMenuFactory

MenuFactory(4 个重载)

签名名称来源父对象
menu(MenuFactory<T>, NonNullSupplier<ScreenFactory<T,SC>>)currentName()S
menu(String, MenuFactory<T>, NonNullSupplier<ScreenFactory<T,SC>>)显式S
menu(P, MenuFactory<T>, NonNullSupplier<ScreenFactory<T,SC>>)currentName()P
menu(P, String, MenuFactory<T>, NonNullSupplier<ScreenFactory<T,SC>>)显式P

ForgeMenuFactory(4 个重载)

签名名称来源父对象
menu(ForgeMenuFactory<T>, NonNullSupplier<ScreenFactory<T,SC>>)currentName()S
menu(String, ForgeMenuFactory<T>, NonNullSupplier<ScreenFactory<T,SC>>)显式S
menu(P, ForgeMenuFactory<T>, NonNullSupplier<ScreenFactory<T,SC>>)currentName()P
menu(P, String, ForgeMenuFactory<T>, NonNullSupplier<ScreenFactory<T,SC>>)显式P
参数类型描述
nameString条目名称(可选)
parentP父对象(可选)
factoryMenuFactory<T>ForgeMenuFactory<T>容器菜单构造器
screenFactoryNonNullSupplier<ScreenFactory<T, SC>>Screen 工厂的 Supplier
  • MenuFactory<T>(int containerId, Inventory playerInv) -> T
  • ForgeMenuFactory<T>(int containerId, Inventory playerInv, FriendlyByteBuf extraData) -> T
java
// 标准 MenuFactory
REGISTRUM.object("my_menu")
    .menu(MyMenu::new, () -> MyScreen::new)
    .lang("My Menu")
    .register();

// ForgeMenuFactory(带额外数据同步)
REGISTRUM.object("my_forge_menu")
    .menu(MyMenu::new, () -> MyScreen::new)
    .register();

Creative Tab 构建器(defaultCreativeTab)

Registries.CREATIVE_MODE_TAB 注册表中注册一个 CreativeModeTab。返回一个 NoConfigBuilder<CreativeModeTab, CreativeModeTab, ...> 以供进一步配置。

不带 config Consumer(4 个重载)

签名名称来源父对象
defaultCreativeTab()currentName()S
defaultCreativeTab(String)显式S
defaultCreativeTab(P)currentName()P
defaultCreativeTab(P, String)显式P

带 config Consumer(4 个重载)

签名名称来源父对象
defaultCreativeTab(Consumer<CreativeModeTab.Builder>)currentName()S
defaultCreativeTab(String, Consumer<CreativeModeTab.Builder>)显式S
defaultCreativeTab(P, Consumer<CreativeModeTab.Builder>)currentName()P
defaultCreativeTab(P, String, Consumer<CreativeModeTab.Builder>)显式P
参数类型描述
nameString选项卡名称。同时将 defaultCreativeModeTab 设置为匹配的 resource key
parentP父对象(可选)
configConsumer<CreativeModeTab.Builder>额外的选项卡配置
java
// 简单选项卡
REGISTRUM.object("my_tab")
    .defaultCreativeTab()
    .lang("My Tab")
    .register();

// 带配置的选项卡
REGISTRUM.object("my_tab")
    .defaultCreativeTab(tab -> tab
        .withSearchBar()
        .withTabsBefore(CreativeModeTabs.BUILDING_BLOCKS))
    .lang("My Tab")
    .register();

// 显式名称 + 父对象 + 配置
REGISTRUM.defaultCreativeTab(myBlockBuilder, "my_tab",
    tab -> tab.icon(() -> new ItemStack(MY_BLOCK.get())))
    .register();

自动生成图标

当未配置图标时,defaultCreativeTab 会使用第一个已注册物品作为后备图标。 如果没有注册任何物品,则使用 Items.AIR 作为占位符。


CreativeTabBuilder(2 个重载)

一个专用的构建器,具有专门的展示物品配置能力。

creativeTab(String, ItemLike)

java
public CreativeTabBuilder<S> creativeTab(String name, ItemLike icon)

使用给定的名称和图标创建一个 CreativeTabBuilderItemLike 会立即包装在一个延迟 Supplier 中。 注册到 Registries.CREATIVE_MODE_TAB

creativeTab(String, Supplier\<ItemLike\>)

java
public CreativeTabBuilder<S> creativeTab(String name, Supplier<ItemLike> icon)

与上面相同,但接受一个 Supplier 以实现延迟的图标解析。

java
REGISTRUM.creativeTab("my_tab", MY_ITEM)
    .displayItems(MY_ITEM, MY_BLOCK, MY_TOOL)
    .lang("My Custom Tab")
    .register();

// 延迟图标
REGISTRUM.creativeTab("my_tab", () -> new ItemStack(MY_DYNAMIC_ITEM))
    .displayItems(MY_ITEM)
    .register();

专用构建器(26.1) 26.1

AnvilLib 26.1 新增,这些构建器涵盖了 NeoForge 特有和高级注册表类型。

Attachment 构建器(2 个重载)

注册一个 attachment 类型(NeoForgeRegistries.Keys.ATTACHMENT_TYPES)。

签名描述
attachment(String, Function<IAttachmentHolder, E>)使用初始化函数创建 attachment
attachment(String, Supplier<E>)使用默认值 Supplier 创建 attachment
参数类型描述
nameString条目名称
const_Function<IAttachmentHolder, E>Supplier<E>attachment 值的构造器
java
// 带初始化函数
REGISTRUM.attachment("my_data", holder -> new MyData())
    .serialize(MyData.CODEC)
    .sync(MyData.STREAM_CODEC)
    .register();

// 带默认值 Supplier
REGISTRUM.attachment("my_data2", MyData::new)
    .serialize(MyData.CODEC)
    .register();

Data Component 构建器(1 个重载)

注册一个 data component 类型(Registries.DATA_COMPONENT_TYPE)。

java
public <E> DataComponentBuilder<E, S> dataComponent(String name)
参数类型描述
nameString条目名称
java
REGISTRUM.dataComponent("my_component")
    .persistent(MyComponent.CODEC)
    .networkSynchronized(MyComponent.STREAM_CODEC)
    .register();

Biome Modifier 构建器(1 个重载)

注册一个 biome modifier 序列化器(NeoForgeRegistries.Keys.BIOME_MODIFIER_SERIALIZERS)。

java
public <T extends BiomeModifier> BiomeModifierBuilder<T, S> biomeModifier(
    String name,
    MapCodec<T> codec
)
参数类型描述
nameString条目名称
codecMapCodec<T>用于序列化的 MapCodec
java
REGISTRUM.biomeModifier("my_modifier", MyModifier.CODEC).register();

Global Loot Modifier 构建器(1 个重载)

注册一个 global loot modifier 序列化器(NeoForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS)。

java
public <T extends IGlobalLootModifier> GlobalLootModifierBuilder<T, S> glm(
    String name,
    MapCodec<T> codec
)
java
REGISTRUM.glm("my_loot_modifier", MyLootModifier.CODEC).register();

Structure Modifier 构建器(1 个重载)

注册一个 structure modifier 序列化器(NeoForgeRegistries.Keys.STRUCTURE_MODIFIER_SERIALIZERS)。

java
public <T extends StructureModifier> StructureModifierBuilder<T, S> structureModifier(
    String name,
    MapCodec<T> codec
)
java
REGISTRUM.structureModifier("my_struct_modifier", MyStructModifier.CODEC).register();

SoundEvent 构建器(1 个重载)

注册一个 SoundEvent(Registries.SOUND_EVENT)。

java
public SoundEventBuilder<S> soundEvent()

使用当前名称(来自 object())。返回一个 SoundEventBuilder,用于配置固定范围和注册。

java
REGISTRUM.object("my_sound")
    .soundEvent()
        .fix(16.0f)  // 可选:固定范围
        .register();

不调用 fix() 时,使用 SoundEvent.createVariableRangeEvent(id)

Condition 构建器(1 个重载)

注册一个 condition 编解码器(NeoForgeRegistries.Keys.CONDITION_CODECS)。

java
public <T extends ICondition> ConditionBuilder<T, S> condition(
    String name,
    MapCodec<T> codec
)
java
REGISTRUM.condition("my_condition", MyCondition.CODEC).register();

受保护的重载

每个 26.1 构建器还有一个 protected 重载,接受 (P parent, String name, ...) 签名,供自定义子类扩展使用。这些不属于公开 API。


注册生命周期

1. object("name")              — 设置当前条目名称
2. block() / item() / 等       — 创建 Builder,存入 registrations Table
3. .lang() .tag() .setData()   — Builder 链配置(在 register() 之前)
4. register()                   — 创建 Registration 对象,返回 RegistryEntry
5. RegisterEvent 触发           — onRegister() 按注册表迭代条目
6. RegisterEvent (LOWEST)       — onRegisterLate() 调用 afterRegisterCallbacks
7. FMLCommonSetupEvent          — OneTimeEventReceiver 清理 RegisterEvent 监听器
8. GatherDataEvent.Client       — (仅数据生成)onData() 启动数据生成

内部 Registration<R, T>

java
// package-private
// 字段:Identifier name, ResourceKey<Registry<R>> type,
//         NonNullSupplier<T> creator, RegistryEntry<R,T> delegate,
//         List<NonNullConsumer<? super T>> callbacks

// register(RegisterEvent):
//   T entry = creator.get();
//   event.register(type, rh -> rh.register(name, entry));
//   callbacks.forEach(c -> c.accept(entry));
//   callbacks.clear();

registerEventListeners() 注册的事件监听器

事件优先级处理器
RegisterEvent常规onRegister() —— 按类型注册收集的条目
RegisterEventLOWESTonRegisterLate() —— 执行注册后回调
BuildCreativeModeTabContentsEvent常规onBuildCreativeModeTabContents() —— 填充创造模式选项卡内容
FMLCommonSetupEvent常规通过 OneTimeEventReceiver 清理 RegisterEvent 监听器
GatherDataEvent.Client常规(仅数据生成)通过 OneTimeEventReceiver 调用 onData()

线程安全性

AbstractRegistrum 不是线程安全的。它使用非并发集合(HashBasedTableHashMultimap),并管理有状态的 currentName

  • 所有注册必须在模组构造@Mod 构造函数)期间同步完成
  • 数据生成回调通过 genData() 串行执行
  • doDatagen 使用 NonNullSupplier.lazy() 实现安全的一次性延迟求值

错误参考

错误原因解决方案
"Current name not set"在依赖名称的方法之前未调用 object()调用 object("name") 或使用显式名称重载
"Unknown registration <name> for type <registry>"get(name, type) 引用了不存在的注册项确保在检索之前已创建注册项
"Cannot get data provider before datagen is started"在数据生成之外调用 getDataProvider()仅在 GatherDataEvent 期间调用
"Cannot add data generator after construction of root generator"在根生成器构造之后调用 addDataGenerator()在数据生成开始之前注册数据生成器
"Found unused register callbacks"(开发环境)回调引用了从未注册的条目检查每个 addRegisterCallback() 是否有对应的条目

BuilderCallback

连接构建器与注册系统的函数式接口。由 AbstractRegistrum.accept() 实现。

java
@FunctionalInterface
public interface BuilderCallback {
    <R, T extends R> RegistryEntry<R, T> accept(
        String name,
        ResourceKey<? extends Registry<R>> type,
        Builder<R, T, ?, ?> builder,
        NonNullSupplier<? extends T> factory,
        NonNullFunction<DeferredHolder<R, T>, ? extends RegistryEntry<R, T>> entryFactory
    );

    // 简化重载(使用默认 RegistryEntry 包装器)
    default <R, T extends R> RegistryEntry<R, T> accept(
        String name,
        ResourceKey<? extends Registry<R>> type,
        Builder<R, T, ?, ?> builder,
        NonNullSupplier<? extends T> factory
    );
}

完整示例

java
@Mod("mymod")
public class MyMod {
    public static final Registrum REGISTRUM = Registrum.create("mymod");

    // Block + BlockItem + BlockEntity
    public static final BlockEntry<MyBlock> MY_BLOCK = REGISTRUM
        .object("my_block")
        .block(MyBlock::new)
            .properties(p -> p.strength(3.0f).requiresCorrectToolForDrops())
            .simpleItem()
            .blockEntity(MyBlockEntity::new)
                .renderer(() -> ctx -> new MyBlockEntityRenderer(ctx))
                .build()
            .lang("My Block")
            .tag(BlockTags.MINEABLE_WITH_PICKAXE)
            .register();

    // Item
    public static final ItemEntry<MyItem> MY_ITEM = REGISTRUM
        .object("my_item")
        .item(MyItem::new)
            .tab(CreativeModeTabs.TOOLS)
            .lang("My Item")
            .register();

    // Entity
    public static final EntityEntry<MyEntity> MY_ENTITY = REGISTRUM
        .object("my_entity")
        .entity(MyEntity::new, MobCategory.CREATURE)
            .renderer(() -> ctx -> new MyEntityRenderer(ctx))
            .properties(b -> b.sized(0.6f, 1.8f))
            .attributes(MyEntity::createAttributes)
            .lang("My Entity")
            .register();

    // 26.1:Data component
    public static final DataComponentEntry<MyData> MY_COMPONENT = REGISTRUM
        .dataComponent("my_component")
            .persistent(MyData.CODEC)
            .networkSynchronized(MyData.STREAM_CODEC)
            .register();

    public MyMod(IEventBus modBus) {
        REGISTRUM.addRegisterCallback(Registries.BLOCK, () ->
            LOGGER.info("All blocks registered!"));
    }
}

Released under the CC-BY-NC-SA 4.0 License.