# SlayMaple [MapleStory Worlds(MSW)](https://maplestoryworlds.nexon.com/) 기반으로 제작하는 **Slay the Spire 풍 덱빌더 로그라이크** 월드. 턴제 카드 전투, 덱 구성, 보상 선택, 맵 노드 진행을 메이플 월드 위에서 구현하는 것을 목표로 합니다. > 이 저장소는 MSW **로컬 워크스페이스(Local Workspace)** 데이터를 git으로 형상관리하기 위한 것입니다. > 공동작업자는 이 저장소를 통해 월드 데이터를 주고받습니다. (클라우드 공동제작 모드 미사용) --- ## 협업 방식 (중요) MSW에는 두 가지 공동작업 모드가 있고, 이 프로젝트는 **로컬 워크스페이스 + git** 방식을 사용합니다. | | 클라우드 공동제작 | **로컬 워크스페이스 + git (이 프로젝트)** | |---|---|---| | 데이터 위치 | 넥슨 클라우드 단일 월드 | 각자 PC 로컬 + git 원격 | | 공유 단위 | Check In / Check Out | `git commit` / `push` / `pull` | | 충돌 처리 | 엔티티 잠금 | git merge | > ⚠️ 로컬 워크스페이스를 켜면 메이커 내 실시간 동기화(클라우드 공동제작)는 비활성화됩니다. > 따라서 **변경 공유는 전적으로 git을 통해** 이루어집니다. ### 내 작업을 공유하기 ```bash git add . git commit -m "작업 내용" git push ``` ### 공동작업자 작업 받아오기 ```bash git pull ``` 받아온 뒤, 메이커에서 **로컬 워크스페이스를 다시 로드(reload)** 해야 새 codeblock/모델 파일이 에디터 상태로 반영됩니다. > 💡 같은 파일을 동시에 수정하면 git 충돌이 날 수 있으니, **서로 다른 맵/codeblock/UI를 나눠서** 작업하는 것을 권장합니다. --- ## 디렉토리 구조 ``` slaymaple/ ├── data/ # 게임 데이터 단일 소스 (생성기가 읽어 주입) │ ├── cards.json # 카드 정의 + 시작 덱 │ ├── enemies.json # 적 정의(슬라임/정예/보스) + activeEnemy │ ├── map.json # 분기 맵 DAG (노드 type/enemy/row/col/next) │ └── relics.json # 유물 정의 + 시작 유물 + 풀 ├── Global/ # 월드 전역 설정 · 공용 모델 · 게임로직 │ ├── common.gamelogic # SlayDeckController 부착 지점 (카드 UI 전투) │ ├── DefaultPlayer.model # 플레이어 모델 (턴전투용 이동 정지 freeze 적용) │ ├── *.model # 몬스터 등 공용 모델 (freeze 적용) │ ├── WorldConfig.config # 월드 설정 │ └── ... ├── RootDesk/ │ └── MyDesk/ # 작업용 책상 — codeblock(스크립트)·모델·타일셋 │ ├── SlayDeckController.codeblock # 게임 전체 컨트롤러 (생성물, 직접 편집 금지) │ ├── Monster.codeblock # 필드 액션 몬스터 (HP·피격·리스폰, 카드 전투와 별개) │ ├── MonsterAttack.codeblock · PlayerAttack.codeblock · PlayerHit.codeblock │ ├── UIPopup.codeblock · UIToast.codeblock │ └── RectTileData_Henesys.tileset ├── map/ │ └── map01.map ~ map11.map # 맵 11종 (공식 배경 + STS풍 우측 배치) ├── tools/ # 결정적 생성기·도구 (주체별 폴더, 단일 소스) │ ├── deck/ # gen-slaydeck.mjs(★게임 전체 생성: 카드/덱·맵·상점·유물·메인메뉴 UI+SlayDeckController+common) · gen-cardhand.mjs(손패 초기 생성) │ ├── map/ # gen-maps.mjs(맵 생성) │ ├── camera/ # gen-camera.mjs(맵별 고정 카메라 codeblock) │ ├── player/ # freeze-turn-player.mjs(이동 정지) · gen-player-lock.mjs(입력 차단·시선 고정 codeblock) │ ├── monster/ # freeze-turn-monsters.mjs(필드 몬스터 AI/이동 정지) │ └── balance/ # sim-balance.mjs(밸런스 시뮬·몬테카를로) · sim-balance.test.mjs ├── ui/ # UI 그룹 (Default / Popup / Toast) ├── docs/ │ ├── slaymaple_basic_framework.md # 전투 프레임워크 설계 문서 │ └── superpowers/specs|plans/ # 각 기능 설계·구현 계획 문서 └── README.md ``` > `.mcp.json`, `.codex/` 는 **Authorization 토큰이 포함**되어 있어 git에서 제외됩니다(`.gitignore`). 각자 로컬에서 직접 구성하세요. --- ## 게임 프레임워크 현황 **STS풍 덱빌더 런이 end-to-end로 완성**됐습니다 — 메인 메뉴 → 분기 맵 → 전투/엘리트/상점/휴식 → 카드 보상·덱 성장 → 유물 → 보스 → 다음 막 → 런 클리어. 게임 전체는 `/common` 엔티티에 부착된 **`SlayDeckController` 단일 컴포넌트**로 동작하며, 모든 산출물(`ui/DefaultGroup.ui` · `SlayDeckController.codeblock` · `common.gamelogic`)은 **`tools/deck/gen-slaydeck.mjs` 단일 소스에서 생성**됩니다(직접 편집 금지, 결정적 출력). 게임 데이터는 **`data/*.json`** 가 단일 소스. ### 구현된 기능 | 영역 | 내용 | |---|---| | **메인 메뉴** | "슬레이 메이플" 타이틀 + "새 게임" → 런 시작 (`OnBeginPlay`→`ShowMainMenu`) | | **카드 전투** | 에너지 3·매 턴 5장 드로우·버림/재셔플·카드 클릭 사용. 카드 3종(타격/방어/강타, `damage`/`block` 수치). 적 HP/방어/의도(결정적 사이클·다음 행동 미리 표시). 데미지는 방어 우선 차감. 승/패·입력 잠금 | | **런 영속** | HP·골드·`RunDeck`(보유 카드)가 전투 간 유지. 시작 덱 10장 | | **전투 보상** | 승리 시 카드 3중 1택(덱 추가)·골드, 또는 건너뛰기 | | **분기 맵** | 작성된 DAG(`data/map.json`)에서 다음 노드 선택. 노드 타입 전투/엘리트/보스(적 데이터 차등), 상점/휴식. 도달 가능 노드만 선택 | | **상점/휴식** | 상점=골드로 카드·유물 구매. 휴식=HP 회복 | | **유물** | 훅 패시브(`combatStart`/`turnStart`/`cardPlayed`/`combatReward`). 획득 3경로(시작·엘리트 승리·상점). 유물 4종 | | **멀티 act** | 보스 클리어→다음 막(적 스케일 `1+(막-1)*0.6`), 최종 막 보스에서 런 클리어. 막 수 3 | | **밸런스 시뮬** | `tools/balance/sim-balance.mjs` — 몬테카를로 N회 전투로 승률·턴·OP 카드 리포트 | | **턴전투 freeze** | 카드 전투 중 필드 몬스터/플레이어 이동·AI 정지(`freeze-turn-*.mjs`) | > ⚠️ 플레이어 HP(80)·적 수치·골드/카드값(15/30/유물60)·막 배율 등은 **밸런싱 미조정 placeholder**입니다. 추후 카드·적은 **메이플스토리 IP**에 맞춰 디벨롭 예정이며, 밸런싱은 `sim-balance.mjs`로 검증합니다. ### 유용한 스크립트 호출 `/common` 엔티티(또는 Play Test 컨텍스트)에서: ```lua local c = _EntityService:GetEntityByPath("/common").SlayDeckController c:StartNewGame() -- 메뉴 → 런 시작 c:PickNode("A") -- 맵 노드 선택 → 전투/상점/휴식 c:PlayCard(1) -- 손패 slot 카드 사용 c:EndPlayerTurn() -- 턴 종료 → 적 턴 → 다음 턴 c:PickReward(1) -- 보상 카드 1택(0=건너뛰기) c:BuyCard(1) / c:BuyRelic() -- 상점 구매 ``` 밸런스 검증: `node tools/balance/sim-balance.mjs [N] [--seed S]` · 테스트: `node --test tools/balance/sim-balance.test.mjs`. 상세 설계는 [`docs/slaymaple_basic_framework.md`](docs/slaymaple_basic_framework.md) 및 `docs/superpowers/specs/` 참조. --- ## 아키텍처 메모 현재 게임 전체 로직이 `SlayDeckController` 단일 codeblock에 모여 있습니다. 초기 설계 문서가 제안한 3분할(`SlayCardCatalog`/`SlayRunState`/`SlayCombatManager`)은 **기능적으로 모두 구현**됐으나 아직 한 컴포넌트 안에 있습니다. 시스템이 더 커지면 그때 분리를 고려합니다. 카드/적/맵/유물 데이터는 이미 `data/*.json`로 외부화돼 있습니다. --- ## 다음 구현 단계 (후속 후보) - [x] 단일 전투 루프 · 데이터 외부화 · 밸런스 시뮬 · 런 루프 · 분기 맵 · 상점/휴식 · 유물 · 멀티 act **(완료)** - [ ] 저장/불러오기(런 영속 직렬화) — MSW 저장 API 필요 - [ ] 카드 제거(상점) — 덱 전체 보기 UI 필요 - [ ] 경제 밸런싱 튜닝(골드/승리 15 < 카드값 30 < 유물 60) — `sim-balance.mjs` 활용 - [ ] 메이플스토리 IP 기반 카드·적·배경 콘텐츠 확장 - [ ] 막별 다른 맵 디자인·이벤트 노드 --- ## 신규 참여자 셋업 1. 저장소 클론 ```bash git clone https://gitea.gahusb.synology.me/gahusb/maplecontest.git slaymaple ``` 2. MSW Maker에서 이 폴더를 **로컬 워크스페이스 경로**로 지정해 월드 열기 3. `.mcp.json` / `.codex/` 는 git에 없으므로, 본인 토큰으로 직접 생성 (MCP·Codex 사용 시) 4. 작업 전 항상 `git pull`, 작업 후 `git add/commit/push`