Skip to main content

Entry Types

RegistryLib provides specialized Entry types that wrap DeferredHolder with convenience helpers. All entry types extend RegistryEntry<R, T> and are lazily resolved —the underlying object is created only when NeoForge's registration event fires.

note

All entry types also implement Holder-style interfaces. When an API expects a Holder<Item>, Holder<Block>, or Holder<Fluid>, you can pass the entry directly.

ItemEntry<T>

Extends: RegistryEntry<Item, T>

MethodReturn typeDescription
get()TGet the registered Item instance
asStack()ItemStackCreate a default ItemStack (count 1)
asStack(int count)ItemStackCreate an ItemStack with the specified count
readOnlyStack()ItemStackDefensive copy of a cached ItemStack (count 1); safe against external mutation
asResource()ItemResourceItemResource wrapper for transfer APIs

Usage example:

ItemEntry<Item> COPPER_COIN = REGISTRYLIB.item("copper_coin", Item::new)
.lang("Copper Coin")
.register();

// Later in code
ItemStack stack = COPPER_COIN.asStack(16);
Item item = COPPER_COIN.get();

BlockEntry<T>

Extends: RegistryEntry<Block, T>

MethodReturn typeDescription
get()TGet the registered Block instance
getDefaultState()BlockStateBlock's default BlockState for placement or configuration

Usage example:

BlockEntry<Block> DECORATIVE_STONE = REGISTRYLIB.block("decorative_stone", Block::new)
.initialProperties(() -> Blocks.STONE)
.simpleItem()
.register();

// Later in code
BlockState state = DECORATIVE_STONE.getDefaultState();

FluidEntry<T>

Extends: RegistryEntry<Fluid, T>

The most feature-rich entry type. Provides access to the entire fluid family (source, flowing, block, bucket) from a single reference.

MethodReturn typeDescription
get()TGet the flowing fluid
getSource()FluidGet the source fluid
getType()FluidTypeGet the FluidType
getBlock()LiquidBlockGet the fluid block (if registered)
getBucket()ItemGet the bucket item (if registered)
asStack()FluidStackCreate a FluidStack (1000 mB)
asStack(long amount)FluidStackCreate a FluidStack with the specified amount
readOnlyStack()FluidStackCached read-only FluidStack (1000 mB); avoids repeated allocations
asResource()FluidResourceFluidResource wrapper for transfer APIs
warning

getBlock() and getBucket() return null if the fluid was registered without .block(...) or .bucket(...) in its builder chain.

Usage example:

FluidEntry<BaseFlowingFluid.Flowing> MOLTEN_GOLD = REGISTRYLIB
.fluid("molten_gold", STILL_TEXTURE, FLOW_TEXTURE)
.lang("Molten Gold")
.block(b -> {})
.bucket(b -> {})
.register();

// Later in code
FluidStack stack = MOLTEN_GOLD.asStack(500);
Fluid source = MOLTEN_GOLD.getSource();
Item bucket = MOLTEN_GOLD.getBucket();

BlockEntityTypeEntry<T>

Extends: RegistryEntry<BlockEntityType<?>, BlockEntityType<T>>

MethodReturn typeDescription
get()BlockEntityType<T>Get the BlockEntityType

Host block binding is configured during registration via validBlock() or validBlocks() on the builder:

BlockEntityTypeEntry<MyBlockEntity> MY_BE = REGISTRYLIB
.blockEntity("my_be", MyBlockEntity::new)
.validBlock(MY_BLOCK)
.renderer(() -> MyBlockEntityRenderer::new)
.register();
tip

Bind multiple blocks with validBlocks(block1, block2, ...) when the same BlockEntity type is shared across several blocks.

EntityEntry<T>

Extends: RegistryEntry<EntityType<?>, EntityType<T>>

MethodReturn typeDescription
get()EntityType<T>Get the EntityType
is(entity)booleanCheck if an Entity instance is of this type

Usage example:

EntityEntry<CrystalGuardian> CRYSTAL_GUARDIAN = REGISTRYLIB
.<CrystalGuardian>entity("crystal_guardian", CrystalGuardian::new, MobCategory.MONSTER)
.attributes(CrystalGuardian::createAttributes)
.renderer(() -> CrystalGuardianRenderer::new)
.register();

// Later in code
EntityType<CrystalGuardian> type = CRYSTAL_GUARDIAN.get();
boolean match = CRYSTAL_GUARDIAN.is(someEntity);
tip

Entities with attributes (any LivingEntity subclass) must call .attributes() on the builder. Omitting it causes a crash at entity spawn time.

See Also