feat(monster): 적 종별 모델(프리팹) + 스테이지 로스터 배치 #107

Merged
gahusb merged 12 commits from feature/monster-models into main 2026-07-03 01:34:27 +09:00
Owner

요약

적 18종 각각의 전용 .model(프리팹)을 생성기로 저작하고, 맵이 data/encounters.json 로스터대로 해당 모델 인스턴스를 배치하도록 개편합니다. 외형이 적 정체성(EnemyId)과 항상 일치하고, 능력치·외형·배치가 관심사별로 분리됩니다.

⚠️ 메이커 플레이테스트 전입니다. RUID 수확(Task 2)·메이커 검증(Task 7)은 메이커 실행이 필요해 보류 중 — 검증 완료 후 머지 권장.

배경 (해결한 문제)

  • 기존 gen-map-encounters.mjs가 외형 RUID 9종을 EnemyId와 무관하게 랜덤 배정 → "슬라임(스탯)인데 버섯(외형)" 불일치.
  • 일반/엘리트/보스 풀이 도구 내 전역 상수라 map01~05가 같은 몬스터 구성.

변경 내용

  • data/enemies.json: 적 외형(appearance{sheet,box,off}) 필드 신설 — map01 메이커 큐레이션 9종을 흡수(단일 소스화). luaEnemiesTable 화이트리스트 밖이라 codeblock 불변(diffcheck IDENTICAL).
  • data/encounters.json 신설: 맵별 combat/elite/boss 로스터.
  • tools/monster/lib/monster-model.mjs 신설: 모델·인스턴스 공용 빌더(fs 접근 없는 순수 함수) + 단위테스트 6건.
  • tools/monster/gen-monster-models.mjs 신설: 적 종별 .model emit(model://monster-<id> 네임스페이스·EntryKey 충돌 가드·외형/EnemyId 베이크·태생 AI-free). 현재 9종 생성(나머지 9종은 Task 2 후).
  • tools/map/gen-map-encounters.mjs 개편: 로스터 기반 종별 모델 인스턴스 배치. 준비도 가드appearance 미보유 적이 포함된 맵은 재생성 스킵(기존 보존)이라 map01만 재생성, map02~05는 Task 2 후 자동 완성.
  • tools/monster/gen-combat-monster.mjs 축소: CombatMonster.codeblock 생성만(맵 부착은 encounters 생성기로 흡수).
  • RULES §1·README 반영.

검증

  • 단위 테스트 103/103 PASS(monster-model 6건 포함)
  • diffcheck 산출물 바이트-동일 · cbgap GAP 0 · cbprops 0 · cardkinds 정합
  • 생성기 2회 실행 결정론 확인 · map01 9마리 외형=이름=EnemyId=modelId 100% 일치
  • 미완: 메이커 플레이테스트(Task 7) · 미확보 9종 RUID 수확(Task 2)

남은 작업(메이커 세션)

  • Task 2: slime·pig·mushmom 등 9종 공식 리소스 RUID 수확 → enemies.json appearance 채움 → 생성기 재실행하면 map02~05·모델 18종 자동 완성.
  • Task 7: reload·빌드 0에러·플레이테스트·모델 브라우저 베이크 확인.
## 요약 적 18종 각각의 전용 `.model`(프리팹)을 생성기로 저작하고, 맵이 `data/encounters.json` 로스터대로 해당 모델 인스턴스를 배치하도록 개편합니다. 외형이 적 정체성(EnemyId)과 항상 일치하고, 능력치·외형·배치가 관심사별로 분리됩니다. > ⚠️ **메이커 플레이테스트 전입니다.** RUID 수확(Task 2)·메이커 검증(Task 7)은 메이커 실행이 필요해 보류 중 — 검증 완료 후 머지 권장. ## 배경 (해결한 문제) - 기존 `gen-map-encounters.mjs`가 외형 RUID 9종을 EnemyId와 무관하게 랜덤 배정 → "슬라임(스탯)인데 버섯(외형)" 불일치. - 일반/엘리트/보스 풀이 도구 내 전역 상수라 map01~05가 같은 몬스터 구성. ## 변경 내용 - **`data/enemies.json`**: 적 외형(`appearance{sheet,box,off}`) 필드 신설 — map01 메이커 큐레이션 9종을 흡수(단일 소스화). `luaEnemiesTable` 화이트리스트 밖이라 **codeblock 불변**(diffcheck IDENTICAL). - **`data/encounters.json`** 신설: 맵별 combat/elite/boss 로스터. - **`tools/monster/lib/monster-model.mjs`** 신설: 모델·인스턴스 공용 빌더(fs 접근 없는 순수 함수) + 단위테스트 6건. - **`tools/monster/gen-monster-models.mjs`** 신설: 적 종별 `.model` emit(`model://monster-<id>` 네임스페이스·EntryKey 충돌 가드·외형/EnemyId 베이크·태생 AI-free). 현재 9종 생성(나머지 9종은 Task 2 후). - **`tools/map/gen-map-encounters.mjs`** 개편: 로스터 기반 종별 모델 인스턴스 배치. **준비도 가드** — `appearance` 미보유 적이 포함된 맵은 재생성 스킵(기존 보존)이라 map01만 재생성, map02~05는 Task 2 후 자동 완성. - **`tools/monster/gen-combat-monster.mjs`** 축소: `CombatMonster.codeblock` 생성만(맵 부착은 encounters 생성기로 흡수). - **RULES §1·README** 반영. ## 검증 - 단위 테스트 **103/103 PASS**(monster-model 6건 포함) - `diffcheck` 산출물 바이트-동일 · `cbgap` GAP 0 · `cbprops` 0 · `cardkinds` 정합 - 생성기 2회 실행 결정론 확인 · map01 9마리 `외형=이름=EnemyId=modelId` 100% 일치 - ⏳ 미완: 메이커 플레이테스트(Task 7) · 미확보 9종 RUID 수확(Task 2) ## 남은 작업(메이커 세션) - Task 2: slime·pig·mushmom 등 9종 공식 리소스 RUID 수확 → enemies.json appearance 채움 → 생성기 재실행하면 map02~05·모델 18종 자동 완성. - Task 7: reload·빌드 0에러·플레이테스트·모델 브라우저 베이크 확인.
gahusb added 6 commits 2026-07-02 14:01:05 +09:00
map01 메이커 큐레이션 외형을 enemies.json으로 흡수(단일 소스화).
encounters.json: map01=현 실태, map02~05=티어별 초안(기존 18종 내).
appearance는 luaEnemiesTable 화이트리스트 밖이라 codeblock 불변(diffcheck IDENTICAL).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011xhLoQbJvQYL65kBtDNDTy
buildMonsterModel(.model 골격 복제·외형/EnemyId 베이크·AI-free) +
buildMonsterInstance(맵 엔티티) + modelEntryId. fs 접근 없는 순수 함수.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011xhLoQbJvQYL65kBtDNDTy
단일 소스 data/enemies.json appearance → Models/Monsters/<enemyId>.model.
EntryKey model://monster-<id> 네임스페이스(기존 모델과 충돌 가드), 태생 AI-free.
appearance 미확보 9종(slime 등)은 Task 2(RUID 수확) 후 추가 예정.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011xhLoQbJvQYL65kBtDNDTy
MONSTER_VARIANTS 랜덤 외형 제거(외형=enemies.json appearance로 정체성 고정).
buildMonsterInstance로 종별 모델(monster-<id>) 인스턴스 배치, 준비도 가드로
appearance 미보유 로스터 맵은 보존(Task 2 RUID 수확 후 재생성).
gen-combat-monster는 codeblock 생성만(맵 부착은 encounters 생성기로 흡수).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011xhLoQbJvQYL65kBtDNDTy
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011xhLoQbJvQYL65kBtDNDTy
RULES §1 표에 Models/Monsters/<enemyId>.model 행 + 보조 생성기 3종 갱신.
README 디렉토리 구조·기능 표(몬스터 종별 모델)·재생성 명령 반영.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011xhLoQbJvQYL65kBtDNDTy
gahusb added 2 commits 2026-07-02 19:57:58 +09:00
MSW 자산 검색으로 공식 maplestory 몹 클립 확보:
- slime(0210100)·slime_elite/boss(슬라임 재사용, box 스케일)
- pig(1210100)·mushmom(6130101)·blue_mushroom(2220110)
- red_snail·modified_snail(snail 0100100 — 빨강변형 0100102는 카탈로그 부재)
stump(나무토막)는 카탈로그에서 미발견 → 미보유 유지(map04 준비도 가드 스킵).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011xhLoQbJvQYL65kBtDNDTy
적 외형 8종 추가로 모델 8개 신규(slime·pig·mushmom·blue_mushroom 등),
map02/03/05가 준비도 가드 통과해 종별 모델 인스턴스로 재배치.
map04는 stump 미보유로 보존(스킵).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011xhLoQbJvQYL65kBtDNDTy
gahusb added 2 commits 2026-07-02 20:24:46 +09:00
MSW "나무토막" localized 검색에 잡힌 유일한 저레벨 몹 클립셋(1110101:
stand/hit/die/move) 채택. 시각 확정은 플레이테스트(map04)에서.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011xhLoQbJvQYL65kBtDNDTy
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011xhLoQbJvQYL65kBtDNDTy
gahusb added 2 commits 2026-07-03 01:18:27 +09:00
메이커가 엔티티의 원본 모델을 origin.entry_id로 해석하는데, entry_id를
enemyId("junior_bugi")로 넣어 model://monster-junior_bugi(실제 EntryKey)와
불일치 → [LEA-3028] MissingModel로 전 몬스터 미표시. entry_id를
modelEntryId(=modelId="monster-<id>")로 수정. 메이커 인게임 검증: 전투에서
전 종 정상 렌더(stump=1110101도 나무토막 확인).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011xhLoQbJvQYL65kBtDNDTy
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011xhLoQbJvQYL65kBtDNDTy
gahusb merged commit 30c73c9899 into main 2026-07-03 01:34:27 +09:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: gahusb/maplecontest#107