모드를 만들다 보면 꼭 한 놈만 말을 듣고 나머지는 단체로 파업하는 경우가 있음. 내 모드가 딱 그 짝이었음. 튼튼한 '탱커' 주민만 잘 싸우고, 힐러, 궁수, 전사는 그냥 멀뚱멀뚱 구경만 함. 로그엔 에러도 안 찍힘. 대체 뭐가 문제였을까? 기나긴 삽질의 기록을 시작함.

사건의 발단: 왜 너만 일하냐, 탱커!
내 모드의 핵심은 직업별로 특별한 AI를 가진 주민 용사들임. 근데 탱커(갑옷 대장장이)만 제 역할을 하고 나머지는 그냥 바닐라 주민이었음.
결론부터 말하면, AI를 심어주는 '선생님'의 꼼꼼함 차이 때문이었음.
- 성공한 탱커 (꼼꼼한 선생님): 학생(주민)이 (1)학교에 처음 나타났을 때 그리고 (2)스스로 "저 갑옷 만들래요!" 하고 직업을 정했을 때, 두 번이나 찾아가서 "자, 이제 너는 탱커다!" 하고 AI 칩을 심어줌. 기회를 놓칠 리가 없음.
- 실패한 나머지 (게으른 선생님): 학생이 (1)학교에 처음 나타났셔을 때 딱 한 번만 물어봄. 근데 대부분 학생은 처음엔 직업이 없는 '백수' 상태. "전 아직 아무것도 아닌데요?" 라는 대답을 듣고 그냥 가버림. 나중에 학생이 직업을 정해도 다시는 찾아오지 않음. 결국 AI 없는 평범한 주민으로 남게 됨.
▶ 해결: 모든 직업의 EventHandler(선생님)들이 탱커처럼 (1)스폰 시, (2)직업 획득 시 두 번의 기회를 갖도록 코드를 통일함. 이제 모든 주민이 제 역할을 찾기 시작함.

함정 카드 발동: 수많은 에러와의 전쟁
주민들이 일을 시작하나 싶었더니, 이번엔 온갖 에러가 터지기 시작함.
1. ClassCastException: "여긴 서버 세상인데, 왜 클라이언트 규칙을 들이대?"
커스텀 스포너를 설치하는 순간 게임이 터짐. 원인은 ClientLevel cannot be cast to ServerLevel.
- 비유: 마인크래프트는 '눈에 보이는 세상(클라이언트)'과 '실제 규칙이 돌아가는 세상(서버)'으로 나뉨. 몹 스폰 같은 실제 규칙은 당연히 서버 세상에서 처리해야 함.
- 내 실수: 클라이언트인지 서버인지 구분도 안 하고 "무조건 서버 규칙으로 처리해!" 라고 명령함. 당연히 눈에 보이는 세상 담당자는 "그게 뭔데요?" 하면서 게임을 터뜨림.
- ▶ 해결: 코드가 실행되는 곳이 서버 세상일 때만 몹 스폰 로직이 돌아가도록 조건을 추가해줌.

2. IllegalArgumentException: "이력서에 없는 항목은 물어보지 마세요."
이번엔 전사 주민이 스킬을 쓰려다 게임이 터짐. 에러는 Can't find attribute minecraft:generic.attack_damage.
- 비유: 바닐라 주민의 '이력서'에는 "체력", "이속" 항목은 있지만, 싸우질 않으니 "공격력" 항목이 아예 없음.
- 내 실수: 전사 스킬 코드에서 주민에게 다짜고짜 "네 이력서에 적힌 공격력 값 좀 내놔!" 라고 물어봄.
- 게임 반응: "이 이력서엔 그런 항목 없는데요? 잘못된 질문임!" 하고 시스템 전체를 멈춰버림.
- ▶ 해결: 게임이 시작될 때 모든 주민의 이력서에 '공격력: 1.0' 이라는 항목을 기본으로 추가해주는 '법률'을 제정함. 이제 누가 물어봐도 당당히 대답할 수 있게 됨.

3. 자동 등록의 배신: "게시판을 잘 찾아갔어야지!"
코드를 깔끔하게 하려고 @Mod.EventBusSubscriber 라는 '자동 등록' 기능을 썼더니, 이번엔 아예 아무도 일을 안 함.
- 비유: Forge에는 두 개의 공지 게시판이 있음.
- MOD 버스: '게임 로딩 중'에만 공지가 올라오는 학술 동아리 게시판. (아이템/블록 등록 등)
- FORGE 버스: '게임 플레이 중'에 일어나는 모든 일을 알리는 운동부 게시판. (공격, 상호작용 등)
- 내 실수: 주민 AI 이벤트 핸들러(EventHandler) 파일에 어느 게시판으로 갈지 bus=... 설정을 안 적어줌. 얘네는 '운동부 게시판' 공지를 들어야 하는데, 기본값인 '학술 동아리 게시판' 앞에 멍하니 서 있었던 것.
- ▶ 해결: 모든 이벤트 핸들러에 bus = Mod.EventBusSubscriber.Bus.FORGE 라는 주소를 정확히 적어줌. 제자리를 찾은 핸들러들이 드디어 공지를 듣고 일하기 시작함.
-----------------------------------------------------------------------------------------------------------------------------------------
좀비 스포너와 전사주민 추가함
------------------------------------------------------------------------------------------------------------------------------------
오늘의 교훈
- 타이밍이 생명: 코드가 언제 실행되는지(스폰 시? 상호작용 시?) 명확히 아는 게 중요함.
- 기본 스펙 확인: 없는 능력치를 달라고 하면 게임은 터질 뿐. 없으면 만들어주자.
- 자동화의 함정: 편한 기능일수록 원리를 모르면 뒤통수 맞기 딱 좋음.
결국 하루 종일 삽질했지만, 덕분에 Forge의 이벤트 시스템과 자바의 깐깐함에 대해 많이 배운 하루였음. 이제 진짜 주민 용병단 만들러 가야지.
'모딩 > 마인크래프트 모드 개발 일지' 카테고리의 다른 글
| [마인크래프트 모딩] #7 침대 없이 강제 번식시키는 마법의 빵 만들기 (Feat. 무한 버그) (12) | 2025.06.26 |
|---|---|
| [마인크래프트 모딩] #6 "분명 데미지는 들어가는데..." 칼 안 휘두르는 주민, 범인은 의외의 곳에 있었다 (14) | 2025.06.25 |
| [마인크래프트 모드 개발 일지]25.6.22/25.6.23 (0) | 2025.06.23 |
| [마인크래프트 모드 개발 일지]25.06.23 (14) | 2025.06.23 |
| [마인크래프트 모드 개발 일지] 개발 환경 설정하기_모든 삽질의 진짜 범인을 찾아서 (11) | 2025.06.23 |