Installs into .claude/skills of the current project.
Sponsors
SSkills DirectorySkills Directory
Is that skill safe to install?
SSkills DirectorySkills Directory
Know which skills are safe — weekly.
Are you the author of Level?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/snwlee-level)
---
name: level
description: 레벨·맵 디자인 — 장르 루프를 레벨 구조로 옮기고, 난이도 곡선을 설계·검증한다. 절차적 생성은 결정론적인 것만 쓴다. 트리거 "레벨", "맵", "난이도", "스테이지".
---
# 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. 검증
- 모든 목표 지점에 도달 가능한가 (경로 탐색으로 기계 검증)
- 의도하지 않은 지름길이 있는가 — 루프를 건너뛰면 경제가 무너진다
- 각 구간의 예상 소요가 목표 범위 안인가
## 6. 퍼즐 판
판 퍼즐은 생성한 판마다 기계 검증을 붙인다. 플레이로는 늦게 드러나는 두 가지다.
```bash
echo '{"kind":"match3","board":[[1,1,2],[2,3,1],[3,2,3]]}' | node plugins/nereus-game/lib/puzzle-board.mjs
echo '{"kind":"sliding","tiles":[1,2,3,4,5,6,7,8,0],"width":3}' | node plugins/nereus-game/lib/puzzle-board.mjs
```
| 위반 | 뜻 | 대응 |
|---|---|---|
| `initial-match` | 시작부터 3연속 | 공짜 연쇄가 터진다. 채울 때 줄을 완성하는 색을 거부한다 |
| `deadlock` | 어떤 인접 교환도 매치를 못 만든다 | 소프트락. 개수를 유지한 채 섞되 섞은 판도 매치가 없어야 하고, 시도 상한 뒤 새 판 |
| `unsolvable-parity` | 슬라이딩 판이 패리티상 풀 수 없음 | 무작위 섞기는 절반이 이렇다. 숫자 타일 두 개를 바꾸면 뒤집힌다 — 또는 정답에서 역방향 이동으로 섞는다 |
판 규칙은 화면이 아니라 데이터에 둔다 — 애니메이션은 해소 결과를 재생할 뿐이고, 해소가 끝날 때까지 입력을 잠근다.
되돌리기는 판·점수·남은 수·**난수 상태**까지 전부 복원한다(난수를 빼면 되돌리기로 리롤이 된다).
출처: awesome-gamedev-agent-skills `genres/puzzle` (Apache-2.0).
## 하지 말 것
- 난이도를 "느낌"으로 조정하지 않는다. 재시도 횟수와 구간 이탈률로 본다.
- 새 요소를 위험한 곳에서 처음 보여주지 않는다.
- 시드 없는 절차적 생성을 쓰지 않는다.