NeoForge 26.1 Docs
  • 문서
  • 노트
NeoForge 26.1
NeoForge 26.1
v26.1
학습 진도
0 / 77 챕터 완료방문 0
캡스톤 통합 설계 + 의존 구조차원에 보석 광물 배치 (WorldGen)기계 가공 통합 — Crusher로 광물 → 보석 정제차원 전용 새 몹 — GemGuardian이벤트로 모듈 연결사운드·파티클 폴리시마무리와 통합 빌드
마스터캡스톤

차원 전용 새 몹 — GemGuardian

Magic Realm 전용 적대 몹 GemGuardian을 Monster 상속으로 구현합니다. EntityType 등록, AttributeSupplier, 4큐브 GemGuardianModel, MobRenderer 설정까지 단계별로 다룹니다.

차원 전용 새 몹 — GemGuardian

이번 챕터에서는 master_capstone 전용 새 몹 GemGuardian을 만듭니다. GemGuardian은 Magic Realm(차원) 안에서만 스폰되며, 플레이어를 추적해 근접 공격합니다. 처치 시 Ruby Gem 계열 드롭을 제공해 캡스톤 진행 루프의 핵심 축이 됩니다.

이번 챕터에서 다루는 파일:

  • entity/GemGuardianEntity.java — Monster 상속 AI 설정
  • client/model/GemGuardianModel.java — 4큐브 인간형 모델
  • client/renderer/GemGuardianRenderer.java — MobRenderer 연결
  • MasterCapstoneMod.java — EntityType + AttributeSupplier 등록

1. GemGuardianEntity 클래스

examplemod-master-projects/capstone/src/main/java/com/example/master/capstone/entity/GemGuardianEntity.java

public class GemGuardianEntity extends Monster {
 
    public GemGuardianEntity(EntityType<? extends Monster> type, Level level) {
        super(type, level);
    }
 
    public static AttributeSupplier.Builder createAttributes() {
        return Monster.createMonsterAttributes()
                .add(Attributes.MAX_HEALTH, 30.0)
                .add(Attributes.ATTACK_DAMAGE, 6.0)
                .add(Attributes.MOVEMENT_SPEED, 0.25)
                .add(Attributes.FOLLOW_RANGE, 24.0);
    }
 
    @Override
    protected void registerGoals() {
        this.goalSelector.addGoal(0, new FloatGoal(this));
        this.goalSelector.addGoal(1, new MeleeAttackGoal(this, 1.2D, false));
        this.goalSelector.addGoal(2, new WaterAvoidingRandomStrollGoal(this, 1.0D));
        this.goalSelector.addGoal(3, new LookAtPlayerGoal(this, Player.class, 8.0f));
        this.goalSelector.addGoal(4, new RandomLookAroundGoal(this));
 
        this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Player.class, true));
    }
}

속성 설계

속성값역할
MAX_HEALTH30.0HP 15하트 — 기본 좀비(20)보다 강함
ATTACK_DAMAGE6.0근접 3하트 피해
MOVEMENT_SPEED0.25기본 좀비(0.23)보다 약간 빠름
FOLLOW_RANGE24.0기본 16보다 긴 탐지 범위

Goal 우선순위

Goal은 번호가 낮을수록 우선순위가 높습니다. FloatGoal(0)은 물에 빠지지 않는 필수 Goal — Monster 상속 시 반드시 추가하세요.

0: FloatGoal        ← 물에서 떠다니기 (크래시 방지)
1: MeleeAttackGoal  ← 1.2× 이동속도로 돌진 공격
2: WaterAvoidingRandomStrollGoal ← 물 피해 배회
3: LookAtPlayerGoal ← 8블록 이내 플레이어 응시
4: RandomLookAroundGoal ← 무작위 주시

targetSelector:
1: NearestAttackableTargetGoal<Player> ← 플레이어 우선 공격

2. EntityType 등록 + AttributeSupplier

MasterCapstoneMod.java에서 EntityType과 속성을 연결합니다.

public static final DeferredRegister<EntityType<?>> ENTITY_TYPES =
        DeferredRegister.createEntities(MOD_ID);
 
public static final DeferredHolder<EntityType<?>, EntityType<GemGuardianEntity>> GEM_GUARDIAN =
        ENTITY_TYPES.registerEntityType("gem_guardian",
                GemGuardianEntity::new, MobCategory.MONSTER,
                builder -> builder
                        .sized(0.6f, 1.95f)
                        .clientTrackingRange(80));

생성자에서 레지스트리와 이벤트를 연결합니다.

public MasterCapstoneMod(IEventBus modEventBus, ModContainer container) {
    ENTITY_TYPES.register(modEventBus);
    modEventBus.addListener(MasterCapstoneMod::onEntityAttributes);
}
 
@SubscribeEvent
public static void onEntityAttributes(EntityAttributeCreationEvent event) {
    // ⚠️ Monster 상속 Entity는 반드시 여기에 등록해야 합니다.
    // 누락 시 /summon 에서 NullPointerException 발생.
    event.put(GEM_GUARDIAN.get(), GemGuardianEntity.createAttributes().build());
}

⚠️ AttributeSupplier 미등록 → /summon 크래시
Monster를 상속하지만 createAttributes()를 EntityAttributeCreationEvent에 등록하지 않으면:
→ /summon 시 NullPointerException 발생
항상 entity.createAttributes() + event.put 매핑 필수


3. GemGuardianModel — 4큐브 인간형 구조

client/model/GemGuardianModel.java는 텍스처 크기 64×32 기준 인간형 큐브 구조입니다.

public class GemGuardianModel extends EntityModel<LivingEntityRenderState> {
 
    public static final ModelLayerLocation LAYER_LOCATION =
            new ModelLayerLocation(
                    Identifier.fromNamespaceAndPath("master_capstone", "gem_guardian"),
                    "main"
            );
 
    public static LayerDefinition createBodyLayer() {
        MeshDefinition mesh = new MeshDefinition();
        PartDefinition partDef = mesh.getRoot();
 
        partDef.addOrReplaceChild("head",
                CubeListBuilder.create().texOffs(0, 0)
                        .addBox(-4.0f, -8.0f, -4.0f, 8, 8, 8, new CubeDeformation(0.0f)),
                PartPose.offset(0.0f, 0.0f, 0.0f));
 
        partDef.addOrReplaceChild("body",
                CubeListBuilder.create().texOffs(16, 16)
                        .addBox(-4.0f, 0.0f, -2.0f, 8, 12, 4, new CubeDeformation(0.0f)),
                PartPose.offset(0.0f, 0.0f, 0.0f));
 
        // 오른팔, 왼팔, 오른다리, 왼다리 동일 구조로 추가
        // (GemGuardianModel.java 전체 코드 참고)
 
        return LayerDefinition.create(mesh, 64, 32);
    }
 
    @Override
    public void setupAnim(LivingEntityRenderState renderState) {
        this.head.yRot = renderState.yRot * Mth.DEG_TO_RAD;
        this.head.xRot = renderState.xRot * Mth.DEG_TO_RAD;
 
        float pos = renderState.walkAnimationPos;
        float speed = renderState.walkAnimationSpeed;
 
        this.rightArm.xRot = Mth.cos(pos * 0.6662f + Mth.PI) * 2.0f * speed * 0.5f;
        this.leftArm.xRot  = Mth.cos(pos * 0.6662f) * 2.0f * speed * 0.5f;
        this.rightLeg.xRot = Mth.cos(pos * 0.6662f) * 1.4f * speed;
        this.leftLeg.xRot  = Mth.cos(pos * 0.6662f + Mth.PI) * 1.4f * speed;
    }
}

텍스처 레이아웃 (64×32)

UV 좌표  | 파트
---------|--------
0,0      | 머리 (8×8×8)
16,16    | 몸통 (8×12×4)
40,16    | 오른팔 (4×12×4)
40,16 미러 | 왼팔
0,16     | 오른다리 (4×12×4)
0,16 미러  | 왼다리

textures/entity/gem_guardian.png 파일을 이 레이아웃에 맞게 그리면 됩니다.
현재 파일은 테스트용 보라색 Placeholder입니다.


4. GemGuardianRenderer

public class GemGuardianRenderer
        extends MobRenderer<GemGuardianEntity, LivingEntityRenderState, GemGuardianModel> {
 
    private static final Identifier TEXTURE =
            Identifier.fromNamespaceAndPath("master_capstone",
                    "textures/entity/gem_guardian.png");
 
    public GemGuardianRenderer(EntityRendererProvider.Context ctx) {
        super(ctx, new GemGuardianModel(ctx.bakeLayer(GemGuardianModel.LAYER_LOCATION)), 0.5f);
    }
 
    @Override
    public LivingEntityRenderState createRenderState() {
        return new LivingEntityRenderState();
    }
 
    @Override
    public Identifier getTextureLocation(LivingEntityRenderState renderState) {
        return TEXTURE;
    }
}

렌더러와 레이어를 EntityRenderersEvent에 등록합니다.

@SubscribeEvent
public static void onRegisterRenderers(EntityRenderersEvent.RegisterRenderers event) {
    event.registerEntityRenderer(MasterCapstoneMod.GEM_GUARDIAN.get(),
            GemGuardianRenderer::new);
}
 
@SubscribeEvent
public static void onRegisterLayerDefinitions(EntityRenderersEvent.RegisterLayerDefinitions event) {
    event.registerLayerDefinition(GemGuardianModel.LAYER_LOCATION,
            GemGuardianModel::createBodyLayer);
}

두 이벤트 모두 클라이언트 전용입니다. @EventBusSubscriber(modid = ..., value = Dist.CLIENT) 로 등록하거나(26.1.2: bus 속성 없이 버스 자동 판별) 별도 ClientEvents.java로 분리하세요.


5. 자연 스폰 설계 (다음 챕터 예고)

GemGuardian의 자연 스폰은 magic_realm 차원 안에서만 허용해야 합니다. Overworld 스폰은 캡스톤 설계 의도에 맞지 않습니다.

스폰 설정은 챕터 04 (04-event-integration)에서 BiomeModifier + SpawnData 방식으로 구현합니다.

챕터 03 (이번 챕터) — Entity 등록, Goal, 모델, 렌더러
챕터 04 (다음 챕터) — magic_realm 차원 내 자연 스폰 + LivingDeathEvent 드롭 확장

6. 인게임 검증

빌드 후 Minecraft 클라이언트에서 직접 소환해 동작을 확인합니다.

/summon master_capstone:gem_guardian ~ ~ ~

확인 항목:

항목예상 동작
소환 성공콘솔 에러 없이 엔티티가 나타남
플레이어 추적24블록 이내 접근 시 달려옴
근접 공격밀착 시 3하트 피해
HP/data get entity @e[type=master_capstone:gem_guardian,limit=1] Health → 30.0

/summon 직후 NullPointerException이 발생한다면 onEntityAttributes 이벤트 등록이 누락된 것입니다.


7. 이 챕터의 완료 기준

  • GemGuardianEntity.java가 master_capstone:gem_guardian으로 등록됩니다.
  • EntityAttributeCreationEvent에 속성 맵이 등록되어 /summon 크래시가 없습니다.
  • GemGuardianModel과 GemGuardianRenderer가 컴파일되고 레이어 등록이 완료됩니다.
  • 보라색 Placeholder 텍스처로 정상 렌더링이 확인됩니다.
  • 다음 챕터(04)에서 magic_realm 내 자연 스폰과 LivingDeathEvent 확장을 진행합니다.

기계 가공 통합 — Crusher로 광물 → 보석 정제

차원에서 채굴한 Ruby·Sapphire 광물을 master_machine의 Crusher로 가공하는 CrusherRecipe 데이터팩을 capstone에 추가하고, 차원 입장 → 채굴 → 귀환 → 가공의 전체 진행 루프를 완성합니다.

이벤트로 모듈 연결

NeoForge 이벤트 시스템을 활용해 GemGuardian 처치 시 MagicCore를 드롭하고, Ruby 아이템 우클릭으로 PURITY 기반 차원 입장 강화를 표시하는 CapstoneEventHandler를 구현합니다.

On this page

차원 전용 새 몹 — GemGuardian1. GemGuardianEntity 클래스속성 설계Goal 우선순위2. EntityType 등록 + AttributeSupplier3. GemGuardianModel — 4큐브 인간형 구조텍스처 레이아웃 (64×32)4. GemGuardianRenderer5. 자연 스폰 설계 (다음 챕터 예고)6. 인게임 검증7. 이 챕터의 완료 기준
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