NeoForge 26.1 Docs
  • 문서
  • 노트
NeoForge 26.1
NeoForge 26.1
v26.1
학습 진도
0 / 77 챕터 완료방문 0
마스터 트랙 #2: 차원 모드 프로젝트 셋업차원 등록 — 데이터팩 3종 JSON포탈 블록 + 점화 아이템포탈 프레임 인식 로직차원 진입·복귀 로직차원 룰셋 — 낮/밤, 침대, 스카이박스차원 모드 마무리 + JAR 빌드
마스터차원

포탈 블록 + 점화 아이템

MagicPortalBlock(Block 상속, 4×5 프레임 내부)과 MagicIgniter(점화 아이템)를 구현하고 DeferredRegister로 등록합니다. 포탈 형태 검사와 차원 이동은 후속 챕터에서 완성됩니다.

포탈 블록 + 점화 아이템

이 챕터에서는 마법 차원 포탈의 두 핵심 요소를 구현합니다.

  • MagicPortalBlock — 포탈 프레임 내부를 채우는 블록 (충돌 없음, 폭발 저항 최대)
  • MagicIgniter — 포탈 프레임에 우클릭해 불을 붙이는 아이템

포탈 형태(4×5) 검사 로직은 03-portal-shape 챕터에서, 엔티티가 포탈을 통과하는 로직은 04-dimension-entry 챕터에서 추가됩니다. 이 챕터는 블록·아이템 등록 토대를 마련하는 단계입니다.


1. MagicPortalBlock

왜 Block을 상속하는가?

⚠️ NetherPortalBlock 직접 상속 금지

// ❌ Vanilla 구현에 의존 — NeoForge 업데이트 시 호환성이 깨질 수 있음
public class MyPortalBlock extends NetherPortalBlock { ... }
 
// ✅ Block 상속 + entityInside 오버라이드로 차원 이동 직접 구현
public class MyPortalBlock extends Block { ... }

NetherPortalBlock은 내부 상태가 복잡하고 NeoForge 버전마다 구현이 달라질 수 있습니다. Block을 직접 상속하고 필요한 메서드만 오버라이드하면 버전 간 안정성이 높아집니다.

구현

// examplemod-master-projects/dimension/src/main/java/com/example/master/dimension/block/MagicPortalBlock.java
package com.example.master.dimension.block;
 
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockBehaviour;
 
public class MagicPortalBlock extends Block {
 
    public MagicPortalBlock(BlockBehaviour.Properties props) {
        super(props
                .noCollission()           // 엔티티가 블록을 통과 가능
                .strength(-1.0F, 3600000.0F)  // 폭발 저항 최대 (흑요석 수준)
                .noLootTable());          // 파괴해도 드롭 없음
    }
 
    // 다음 챕터(03-portal-shape)에서 점화 시 호출되는 로직 추가
    // entityInside 는 04-dimension-entry 에서 추가
}

Properties 설명

속성의미
noCollission()플레이어/엔티티가 블록을 통과 — 포탈 내부를 걸어 들어가는 효과
strength(-1.0F, 3600000.0F)채굴 불가(-1) · 폭발 저항 최대(3,600,000) — 베드록 수준
noLootTable()파괴해도 아이템을 드롭하지 않음

2. MagicIgniter

점화 아이템은 우클릭한 블록의 바로 위 공기 슬롯에 포탈 블록을 배치합니다. 이번 챕터에서는 단일 블록만 배치하며, 03-portal-shape에서 프레임 전체를 채우도록 교체됩니다.

// examplemod-master-projects/dimension/src/main/java/com/example/master/dimension/item/MagicIgniter.java
package com.example.master.dimension.item;
 
import com.example.master.dimension.MasterDimensionMod;
import net.minecraft.core.BlockPos;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
 
public class MagicIgniter extends Item {
 
    public MagicIgniter(Properties props) {
        super(props);
    }
 
    @Override
    public InteractionResult useOn(UseOnContext context) {
        Level level = context.getLevel();
        BlockPos pos = context.getClickedPos();
 
        // 클라이언트 측은 시각 효과만 — 서버에서 실제 처리
        if (level.isClientSide()) return InteractionResult.SUCCESS;
 
        // 프레임 검사는 03-portal-shape 챕터에서 PortalShape.isValidFrame() 으로 교체
        BlockPos firePos = pos.above();
        if (level.getBlockState(firePos).isAir()) {
            level.setBlock(
                    firePos,
                    MasterDimensionMod.MAGIC_PORTAL.get().defaultBlockState(),
                    11 // UPDATE | NOTIFY_CLIENTS
            );
            level.playSound(
                    null,
                    firePos,
                    SoundEvents.FLINTANDSTEEL_USE,
                    SoundSource.BLOCKS,
                    1.0f,
                    1.0f
            );
            return InteractionResult.SUCCESS;
        }
        return InteractionResult.PASS;
    }
}

useOn 흐름

우클릭 (서버측)
  │
  ├─ pos.above() 가 Air 인가?
  │     ├─ YES → MAGIC_PORTAL 블록 배치 + 부싯돌 사운드 → SUCCESS
  │     └─ NO  → PASS (아무 동작 없음)
  │
  └─ 클라이언트 → 즉시 SUCCESS (서버 결과 대기 없이 피드백)

InteractionResult 선택 이유

값의미언제 사용
SUCCESS동작 완료, 아이템 내구도 소모포탈 블록을 배치했을 때
PASS아무 동작 없음, 기본 블록 상호작용으로 fall-through위 슬롯이 비어있지 않을 때

3. MasterDimensionMod에 등록

DeferredRegister로 BLOCKS와 ITEMS를 선언하고, 생성자에서 이벤트 버스에 등록합니다.

// examplemod-master-projects/dimension/src/main/java/com/example/master/dimension/MasterDimensionMod.java
package com.example.master.dimension;
 
import com.example.master.dimension.block.MagicPortalBlock;
import com.example.master.dimension.item.MagicIgniter;
import com.mojang.logging.LogUtils;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.ModContainer;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.registries.DeferredRegister;
import org.slf4j.Logger;
import java.util.function.Supplier;
 
@Mod(MasterDimensionMod.MOD_ID)
public class MasterDimensionMod {
    public static final String MOD_ID = "master_dimension";
    public static final Logger LOGGER = LogUtils.getLogger();
 
    public static final DeferredRegister.Blocks BLOCKS =
            DeferredRegister.createBlocks(MOD_ID);
 
    public static final DeferredRegister.Items ITEMS =
            DeferredRegister.createItems(MOD_ID);
 
    /** 포탈 내부 블록 */
    public static final Supplier<Block> MAGIC_PORTAL = BLOCKS.registerBlock("magic_portal",
            MagicPortalBlock::new);
 
    /** 점화 아이템 — 스택 1, 내구도 64 */
    public static final Supplier<Item> MAGIC_IGNITER = ITEMS.registerItem("magic_igniter",
            props -> new MagicIgniter(props
                    .stacksTo(1)
                    .durability(64)));
 
    public MasterDimensionMod(IEventBus modEventBus, ModContainer container) {
        LOGGER.info("Master Dimension Mod 로드");
        BLOCKS.register(modEventBus);
        ITEMS.register(modEventBus);
    }
}

등록 체크리스트

항목확인 사항
DeferredRegister.BlockscreateBlocks(MOD_ID) 사용 — Blocks 전용 팩토리
DeferredRegister.ItemscreateItems(MOD_ID) 사용 — Items 전용 팩토리
BLOCKS.register(modEventBus)생성자에서 반드시 호출 — 빠뜨리면 블록이 게임에 등록되지 않음
ITEMS.register(modEventBus)생성자에서 반드시 호출
stacksTo(1)점화 아이템은 단 1개만 들 수 있음
durability(64)64회 사용 후 소모

4. 텍스처 플레이스홀더

이 챕터에서는 실제 텍스처 없이 보라색 16×16 PNG로 블록/아이템을 식별합니다. 텍스처 완성은 후속 챕터에서 진행합니다.

텍스처 파일 위치:

examplemod-master-projects/dimension/src/main/resources/
└── assets/master_dimension/
    ├── textures/block/magic_portal.png    ← 보라색 플레이스홀더 16×16
    ├── textures/item/magic_igniter.png    ← 보라색 플레이스홀더 16×16
    ├── models/block/magic_portal.json
    └── models/item/magic_igniter.json

5. 인게임 검증 안내

포탈 블록과 점화 아이템의 인게임 동작 검증은 다음 챕터들에서 순차적으로 수행합니다.

챕터검증 내용
03-portal-shape4×5 흑요석 프레임 완성 후 MagicIgniter로 점화 → 프레임 내부가 포탈 블록으로 채워짐
04-dimension-entry포탈 블록 안에 들어가면 마법 차원으로 이동
05-finish-build전체 Gradle 빌드 + 인게임 종합 검증

다음 단계

이번 챕터에서 포탈 블록과 점화 아이템의 뼈대를 완성했습니다.

  1. 03-portal-shape — PortalShape 유틸리티로 4×5 흑요석 프레임 검증 + 포탈 블록 전체 배치
  2. 04-dimension-entry — entityInside 오버라이드로 플레이어 차원 이동 로직
  3. 05-finish-build — 통합 빌드 & 인게임 종합 검증

차원 등록 — 데이터팩 3종 JSON

dimension JSON, dimension_type JSON, biome JSON 세 파일로 master_dimension:magic_realm 커스텀 차원을 NeoForge 데이터팩 방식으로 등록하는 전체 과정을 다룹니다.

포탈 프레임 인식 로직

PortalShape 헬퍼 클래스로 흑요석 프레임을 탐색·검증하고, MagicIgniter에서 isValidFrame을 호출해 유효한 프레임에만 포탈 블록을 채우는 로직을 구현합니다.

On this page

포탈 블록 + 점화 아이템1. MagicPortalBlock왜 Block을 상속하는가?구현Properties 설명2. MagicIgniteruseOn 흐름InteractionResult 선택 이유3. MasterDimensionMod에 등록등록 체크리스트4. 텍스처 플레이스홀더5. 인게임 검증 안내다음 단계
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