Files
maplecontest/docs/superpowers/specs/2026-06-11-act-maps-design.md
2026-06-11 08:42:59 +09:00

47 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 막별 맵 전환 + 맵별 인카운터 (P4) — 설계
- 날짜: 2026-06-11
- 상태: 승인됨(사용자 사전 위임). 로드맵 P4/5.
## 1. 배경/목표
map02~11은 SectorConfig에 등록만 되고 게임에서 미사용(모든 전투가 map01). 막(act)이 바뀌어도 같은 맵·같은 몬스터.
**목표**: ① 막별로 다른 물리 맵 사용(맵 차별화가 실제 게임에 보이도록) ② 각 맵에 노드 타입별 몬스터 그룹(combat/elite/boss)을 맵별 테마로 자동 구성.
## 2. 설계
### 2.1 막→맵 매핑 + 텔레포트
- `ACT_MAPS = ['map01','map02','map03']`(ACT_COUNT=3과 일치, 생성기 상수→Lua 주입).
- `CheckCombatEnd` 보스 클리어(다음 막 진행) 분기에서 `Floor` 증가 후 `self:TeleportToActMap()`:
- `_TeleportService:TeleportToMapPosition(_UserService.LocalPlayer, Vector3(-6, 0.03, 0), ACT_MAPS[self.Floor])` (UILogic 공식 예제의 API; 위치는 map01 플레이어 시작권 좌측 지면 — 메이커 검증으로 조정).
- 새 맵 로드 시 그 맵 몬스터들의 `CombatMonster.OnBeginPlay`가 자기등록(기존 0.1s×50 재시도 — 텔레포트 직후는 맵 화면이라 전투 진입 전 등록 여유 충분).
### 2.2 등록 풀의 맵 필터 (크로스맵 오염 방지)
- 텔레포트 후 구 맵 몬스터가 언로드되지 않고 등록 풀에 남을 가능성 대비:
- `RegisterMonster(entity, enemyId, group, mapName)` — CombatMonster가 자기 소속 맵 이름을 전달(`self.Entity.CurrentMapName` 우선, nil이면 부모 체인에서 `/maps/` 직계 자식 이름; 구현 검증).
- `BuildMonsters`: `local pmap = _UserService.LocalPlayer.CurrentMapName``r.map == pmap`인 등록만 사용(+기존 isvalid·group 필터).
### 2.3 맵별 인카운터 자동 구성 (`tools/map/gen-map-encounters.mjs` 신규)
- 대상: map02~map11 (map01은 사용자 저작 유지).
- 각 맵: 기존 `script.Monster` 엔티티 전부 제거 → 그 맵의 첫 몬스터 엔티티를 템플릿으로 6마리 생성:
| Group | 수 | x 위치 | EnemyId(맵 번호 순환) |
|---|---|---|---|
| combat | 3 | 2.3 / 3.8 / 5.2 | orange_mushroom·green_mushroom·pig·blue_mushroom 풀에서 3종 |
| elite | 2 | 3.0 / 5.0 | mushmom·modified_snail 중 |
| boss | 1 | 4.0 | king_slime·slime_boss 중 |
- 외형: gen-maps의 `MONSTER_VARIANTS`(공식 수확 9종 sprite/stand/hit/die) 풀에서 맵 시드(`nn*7919`) 결정론 선택(맵마다 다른 조합) — SpriteRenderer/StateAnimation 덮어쓰기.
- `script.CombatMonster` Group/EnemyId 태그 포함, GUID 결정론(`mapGuid` 패턴), idempotent(전체 교체 방식이라 재실행 동일).
- enemies.json 변경 없음(기존 8타입 재사용 — 스탯 일관).
### 2.4 비범위
- 4막+ / 맵별 배경·노드 그래프 차별화(이미 배경·타일은 맵별 상이), 이벤트 노드(P5).
## 3. 검증
- 생성기 결정론(2회 동일), 각 맵 그룹 구성 JSON 검사(3/2/1·EnemyId·변형 다양성).
- 메이커: 1막 보스 처치→Floor 2→**map02 텔레포트**(카메라/PlayerLock은 전 맵 부착됨)→맵 화면→전투 진입 시 map02 몬스터(combat 3, 새 외형)만 등장·구 맵 미오염→엘리트/보스 노드도 그룹 정상.
## 4. 리스크
- `Entity.CurrentMapName`/플레이어 CurrentMapName 형식("map02"?) — 구현 시 메이커 확인, 불일치 시 경로 기반 폴백.
- 텔레포트 직후 카메라/입력 재설정(MapCamera·PlayerLock OnBeginPlay가 맵 로드마다 도는지) — 검증.
- 구 맵 몬스터 isvalid 동작 — 맵 필터가 1차 방어라 비차단.