Minecraft는 아이템, 블록, 엔티티, 사운드 등 모든 게임 오브젝트를 **레지스트리(Registry)**에 등록해서 관리합니다. 모드가 새 아이템을 추가하려면 이 레지스트리에 직접 참여해야 합니다. NeoForge는 그 과정을 안전하게 처리하는 DeferredRegister를 제공합니다.
// examplemod-template-26.1.2/src/main/java/com/example/examplemod/ExampleMod.java, BLOCKS/ITEMS/CREATIVE_MODE_TABS 필드public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(MODID);public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(MODID);public static final DeferredRegister<CreativeModeTab> CREATIVE_MODE_TABS = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, MODID);
DeferredRegister.Blocks와 DeferredRegister.Items는 각각 블록·아이템 전용 편의 서브클래스입니다. registerSimpleBlock, registerSimpleItem 같은 헬퍼 메서드를 추가로 제공합니다. 그 외 레지스트리는 DeferredRegister.create(Registries.XXX, MODID) 형태를 씁니다.
// examplemod-template-26.1.2/src/main/java/com/example/examplemod/ExampleMod.java, EXAMPLE_ITEM 필드public static final DeferredItem<Item> EXAMPLE_ITEM = ITEMS.registerSimpleItem("example_item", p -> p.food(new FoodProperties.Builder().alwaysEdible().nutrition(1).saturationModifier(2f).build()));
ITEMS.registerSimpleItem("example_item", props -> ...)를 호출하면 DeferredItem<Item>이 반환됩니다. 이 시점에 실제 Item 객체가 만들어지지 않습니다. Item.Properties를 받아 변형하는 팩토리 람다(props -> ...)가 저장될 뿐입니다.
⚠️ NeoForge 26.1.2 — registerItem/registerSimpleItem 사용
26.1.2에서는 registerItem/registerSimpleItem(블록은 registerBlock/registerSimpleBlock) 계열을 써야 합니다. 이 메서드들이 내부에서 Properties.setId(...)를 호출하기 때문입니다. 람다 밖에서 new Item.Properties()를 직접 만들어 넘기는 옛 register(name, () -> new Item(new Item.Properties())) 패턴은 "id not set"으로 크래시합니다.
DeferredItem<Item>은 DeferredHolder<Item, Item>의 서브타입이며, Supplier<Item>을 구현합니다. 실제 Item 인스턴스가 필요할 때는 .get()을 호출합니다.
// examplemod-template-26.1.2/src/main/java/com/example/examplemod/ExampleMod.java, EXAMPLE_TAB 의 icon/displayItems// 크리에이티브 탭 아이콘 설정 — 실제 Item 인스턴스가 필요한 시점에 .get() 호출.icon(() -> EXAMPLE_ITEM.get().getDefaultInstance()).displayItems((parameters, output) -> { output.accept(EXAMPLE_ITEM.get());})