levellisted
Install: claude install-skill snwlee/Nereus
# level
nereus:common 규칙을 따른다. 담당 에이전트: level-designer.
**엔진과 무관하다** — 레벨의 구조와 곡선은 로블록스든 Unity든 같다.
## 1. 루프를 구조로 옮긴다
장르 프로파일의 `loop` 가 레벨의 뼈대다.
```js
import { loadProfile } from "../../lib/profiles.mjs";
loadProfile("sim-tycoon").loop; // 수집 → 판매 → 재투자 → 확장
loadProfile("obby-platformer").loop; // 도전 → 실패 → 재시도 → 통과
```
레벨 하나는 **루프를 최소 한 바퀴 돌 수 있어야 한다.** 한 바퀴가 안 도는 레벨은 레벨이 아니라 장식이다.
루프 한 바퀴에 걸리는 시간을 먼저 정하고(타이쿤 30~90초, 오비 10~30초가 출발점), 그 배수로 레벨을 잡는다.
## 2. 난이도 곡선
톱니 모양으로 만든다 — 올리고, 잠깐 내리고, 더 올린다. 단조 증가는 지치고, 평탄은 지루하다.
| 요소 | 질문 |
|---|---|
| 도입 | 새 요소를 **안전한 곳에서** 먼저 보여줬는가. 위험과 학습을 같은 순간에 주지 않는다 |
| 반복 | 배운 것을 한 번 더 쓰게 했는가. 한 번 쓰고 버리는 요소는 기억되지 않는다 |
| 결합 | 앞의 두 요소를 합쳐 쓰는 지점이 있는가. 여기가 실제 난이도다 |
| 회복 | 실패 후 재시작 지점이 가까운가. 오비에서 이 거리가 곧 이탈률이다 |
체크포인트 간격은 **평균 재시도 횟수**로 역산한다. 한 구간을 5회 넘게 재시도하게 되면 구간을 쪼갠다.
## 3. 밸런싱과 이어 붙인다
레벨 비용 구조를 `nereus-game:balance` 의 `stages` 로 옮겨 시뮬레이터에 넣는다.
- 타이쿤: `bottlenecks` 가 비어야 한다. 못 깨는 단계가 곧 벽이다.
- 오비: `cliffs` 가 이탈 구간이다. 절벽 앞에 중간 구간을 끼워 넣는다.
프로파일의 `balance.failureMode` 가 어느 쪽을 먼저 볼지 정한다.
## 4. 절차적 생성을 쓸 때
**결정론적인 것만 쓴다.** WaveFunctionCollapse·MarkovJunior 는 시드가 같으면 결과가 같아
레벨을 테스트할 수 있다 — 생성물 자체를 회귀 테스트 대상으로 둘 수 있다는 뜻이다.
- 시드를 레벨 데이터에 저장한다. 저장하지 않으면 재현이 불가능하고 버그 신고가 무의미해진다.
- 생성 결과를 **검증 규칙**과 짝지운다(도달 가능한가, 막힌 구간이 없는가, 최소 경로 길이가 범위 안인가).
검증 없는 생성은 무작위 쓰레기를 대량 생산한다.
- LLM 으로 레벨을 생성하지 않는다. 재현이 안 되고 검증도 안 된다.
## 5. 검증
- 모든 목표 지점에 도달 가능한가 (경로 탐색으로 기계 검증)
- 의도하지 않은 지름길이 있는가 — 루프를 건너뛰면 경제가 무너진다
- 각 구간의 예상 소요가 목표 범위 안인가
## 하지 말 것