NeoForge 26.1 Docs
  • 문서
  • 노트
NeoForge 26.1
NeoForge 26.1
v26.1
학습 진도
0 / 77 챕터 완료방문 0
@Mod 클래스와 생성자 패턴이벤트 버스 — Mod / NeoForge 두 가지 차이Registry와 DeferredRegister 개념ModConfigSpec과 설정 GUISLF4J Logger와 로그 레벨클라이언트/서버 분리와 Dist모드 내 다국어 — lang/<locale>.json
모딩 기초

Registry와 DeferredRegister 개념

Minecraft 레지스트리 시스템 개요와 NeoForge의 DeferredRegister 사용 패턴(register, Holder)을 학습합니다.

Registry와 DeferredRegister 개념

Minecraft는 아이템, 블록, 엔티티, 사운드 등 모든 게임 오브젝트를 **레지스트리(Registry)**에 등록해서 관리합니다. 모드가 새 아이템을 추가하려면 이 레지스트리에 직접 참여해야 합니다. NeoForge는 그 과정을 안전하게 처리하는 DeferredRegister를 제공합니다.


1. Minecraft 레지스트리 시스템

Minecraft는 게임 오브젝트를 종류별로 분리된 레지스트리에 보관합니다. 각 레지스트리는 ResourceKey로 식별되며, BuiltInRegistries 클래스에 정적 필드로 노출됩니다.

레지스트리담당 오브젝트
BuiltInRegistries.ITEM아이템
BuiltInRegistries.BLOCK블록
BuiltInRegistries.ENTITY_TYPE엔티티 타입
BuiltInRegistries.SOUND_EVENT사운드 이벤트
BuiltInRegistries.BLOCK_ENTITY_TYPE블록 엔티티 타입
Registries.CREATIVE_MODE_TAB크리에이티브 탭

모드가 새 아이템을 추가할 때는 BuiltInRegistries.ITEM에 등록해야 합니다. 문제는 언제 등록하느냐입니다.


2. 왜 DeferredRegister인가

레지스트리 등록은 타이밍이 중요합니다. Minecraft가 레지스트리를 초기화하기 전에 등록을 시도하면 크래시가 납니다.

잘못된 방법 — 정적 초기화에서 직접 등록

⚠️ 정적 초기화에서 직접 등록 시

// ❌ 잘못됨 — BuiltInRegistries에 직접 register 시 ClassLoader 에러
static {
    BuiltInRegistries.ITEM.register(...);  // RuntimeException
}

클래스가 로드되는 시점에 레지스트리가 아직 준비되지 않았습니다. 항상 DeferredRegister 사용 → 생성자에서 register → modEventBus에 자동 처리.

올바른 방법 — DeferredRegister

DeferredRegister는 등록할 오브젝트를 내부 목록에 모아두고, FML이 적절한 시점(RegisterEvent)에 실제 레지스트리에 등록합니다. 모드 개발자는 타이밍을 신경 쓸 필요가 없습니다.

// examplemod-template-26.1.2/src/main/java/com/example/examplemod/ExampleMod.java, ITEMS 필드
// DeferredRegister.Items — 아이템 전용 편의 서브클래스
public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(MODID);

DeferredRegister.createItems(MODID)는 BuiltInRegistries.ITEM을 대상으로 하는 레지스트리 바구니를 만듭니다. MODID는 등록될 오브젝트의 네임스페이스(examplemod:example_item 형태)를 결정합니다.


3. 사용 패턴

3-1. 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) 형태를 씁니다.

3-2. 오브젝트 등록

// 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"으로 크래시합니다.

3-3. modEventBus에 연결

// examplemod-template-26.1.2/src/main/java/com/example/examplemod/ExampleMod.java, ExampleMod 생성자
public ExampleMod(IEventBus modEventBus, ModContainer modContainer) {
    BLOCKS.register(modEventBus);
    ITEMS.register(modEventBus);
    CREATIVE_MODE_TABS.register(modEventBus);
    // ...
}

생성자에서 ITEMS.register(modEventBus)를 호출해야 합니다. 이 호출이 없으면 바구니에 담아둔 아이템이 실제 레지스트리에 등록되지 않습니다.


4. DeferredHolder와 Supplier

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());
})

.get()은 레지스트리 등록이 완료된 이후에만 유효합니다. 정적 초기화나 생성자 내부에서 .get()을 호출하면 null이 반환되거나 예외가 발생합니다.


5. 전체 흐름 다이어그램

다이어그램 렌더링 중…

6. Identifier와 네임스페이스

레지스트리에 등록된 모든 오브젝트는 Identifier(net.minecraft.resources.Identifier)로 식별됩니다. 26.1.2에서 기존 ResourceLocation은 삭제되고 Identifier로 대체되었습니다. 형식은 네임스페이스:경로입니다.

examplemod:example_item
^^^^^^^^^^ ^^^^^^^^^^^^
네임스페이스  경로 (register 첫 번째 인자)
(MODID)

DeferredRegister.createItems(MODID)에서 MODID가 네임스페이스를 결정합니다. 바닐라 아이템은 minecraft: 네임스페이스를 씁니다. 모드 아이템은 반드시 자신의 mod-id를 네임스페이스로 써야 충돌을 피할 수 있습니다.


7. 자주 쓰는 DeferredRegister 팩토리 메서드

메서드용도
DeferredRegister.createBlocks(MODID)블록 레지스트리
DeferredRegister.createItems(MODID)아이템 레지스트리
DeferredRegister.create(Registries.ENTITY_TYPE, MODID)엔티티 타입
DeferredRegister.create(Registries.SOUND_EVENT, MODID)사운드 이벤트
DeferredRegister.create(Registries.BLOCK_ENTITY_TYPE, MODID)블록 엔티티 타입

요약

  • Minecraft는 모든 게임 오브젝트를 BuiltInRegistries의 레지스트리에 보관합니다.
  • 정적 초기화에서 직접 등록하면 타이밍 문제로 크래시가 납니다. DeferredRegister를 씁니다.
  • DeferredRegister.createItems(MODID)로 바구니를 만들고, registerSimpleItem(name, props -> ...)(또는 registerItem)로 오브젝트를 예약합니다.
  • 생성자에서 ITEMS.register(modEventBus)를 호출해야 실제 등록이 이루어집니다.
  • DeferredItem.get()은 레지스트리 등록 완료 이후에만 호출합니다.

다음 챕터에서는 아이템과 블록을 직접 추가하면서 이 패턴을 실습합니다.

이벤트 버스 — Mod / NeoForge 두 가지 차이

NeoForge 26의 Mod EventBus와 NeoForge EventBus 두 가지를 구분하고 어느 이벤트가 어느 버스에 가는지, 등록 방식 4가지를 학습합니다.

ModConfigSpec과 설정 GUI

NeoForge 26의 ModConfigSpec.Builder로 모드 설정을 정의하고 Mods 메뉴의 Config GUI에서 변경하는 방법을 학습합니다.

On this page

Registry와 DeferredRegister 개념1. Minecraft 레지스트리 시스템2. 왜 DeferredRegister인가잘못된 방법 — 정적 초기화에서 직접 등록올바른 방법 — DeferredRegister3. 사용 패턴3-1. DeferredRegister 선언3-2. 오브젝트 등록3-3. modEventBus에 연결4. DeferredHolder와 Supplier5. 전체 흐름 다이어그램6. Identifier와 네임스페이스7. 자주 쓰는 DeferredRegister 팩토리 메서드요약
NeoForge 26.1 Docs

NeoForge 26.1 모딩 개발 문서 사이트

GitHubDiscord

문서

  • 문서
  • 노트

GitHub

  • GitHub
  • Discord

© 2026 NeoForge 26.1 Docs. 콘텐츠는 MIT 라이선스로 제공됩니다.

Built with Next.js · Tailwind CSS · shadcn/ui