gahusb bdea6a8c28 fix(debug): Ctrl+Shift+E 치트에 체력 회복 추가 (체력+에너지 전체 회복)
원인: Ctrl+Shift+E의 CheatFillEnergy는 #75에서 energy-only로 만들어져
self.Energy만 채우고 self.PlayerHp는 전혀 건드리지 않았다(설계상 체력 미회복).
바인딩·발동은 정상(Ctrl+Shift+C 카드 picker와 동일 입력 메커니즘)이라
에너지는 차지만 체력은 회복된 적이 없었음 → "체력 회복 안됨".

수정: CheatFillEnergy에 self.PlayerHp = self.PlayerMaxHp 추가 + RenderCombat()
호출(HP 표시 갱신). 누르던 Ctrl+Shift+E 그대로 체력+에너지 전체 회복으로 확장.
토스트 "치트: 체력·에너지 회복", README 디버그 단축키 표기도 갱신.

산출물 재생성: SlayDeckController.codeblock. 검증: cbgap GAP 0, JS 41/41.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 01:56:30 +09:00

SlayMaple

MapleStory Worlds(MSW) 기반으로 제작하는 Slay the Spire 풍 덱빌더 로그라이크 월드. 로비 마을에서 NPC와 상호작용해 런을 시작하고, 턴제 카드 전투·덱 구성·보상 선택·절차 생성 맵 진행·전직·영혼 메타 성장을 메이플 월드 위에서 구현합니다.

이 저장소는 MSW 로컬 워크스페이스(Local Workspace) 데이터를 git으로 형상관리하기 위한 것입니다. 공동작업자는 이 저장소를 통해 월드 데이터를 주고받습니다. (클라우드 공동제작 모드 미사용)


협업 방식 (중요)

MSW에는 두 가지 공동작업 모드가 있고, 이 프로젝트는 로컬 워크스페이스 + git 방식을 사용합니다.

클라우드 공동제작 로컬 워크스페이스 + git (이 프로젝트)
데이터 위치 넥슨 클라우드 단일 월드 각자 PC 로컬 + git 원격
공유 단위 Check In / Check Out git commit / push / pull
충돌 처리 엔티티 잠금 git merge

⚠️ 로컬 워크스페이스를 켜면 메이커 내 실시간 동기화(클라우드 공동제작)는 비활성화됩니다. 따라서 변경 공유는 전적으로 git을 통해 이루어집니다.

내 작업을 공유하기

git add .
git commit -m "작업 내용"
git push

공동작업자 작업 받아오기

git pull

받아온 뒤, 메이커에서 로컬 워크스페이스를 다시 로드(reload) 해야 새 codeblock/모델/맵 파일이 에디터 상태로 반영됩니다.

💡 같은 파일을 동시에 수정하면 git 충돌이 날 수 있으니, 서로 다른 맵/codeblock/UI를 나눠서 작업하는 것을 권장합니다. ⚠️ git pull 후 reload를 빠뜨리면 메이커의 stale 상태가 디스크를 덮어쓸 수 있습니다. 재생성 후에도 reload → 빌드 콘솔 0 에러 확인.


디렉토리 구조

slaymaple/
├── data/                       # 게임 데이터 단일 소스 (생성기가 읽어 주입). 맵은 정적 데이터 없음(절차 생성)
│   ├── cards.json              # 카드 122장(클래스·2차전직별 + 저주) + 클래스별 시작 덱
│   ├── enemies.json            # 적 12종(일반/정예/보스, 디버프 인텐트 포함)
│   ├── potions.json            # 물약 6종 + 드랍률·슬롯·상점가
│   ├── relics.json             # 유물 19종(StS 효과 × 메이플 장비) + 시작 유물 + 풀
│   ├── cardframes.json         # 커스텀 카드 프레임 3종(전사/마법사/도적 × normal/unique/legend) + 보상 등급 가중치
│   └── camera.json             # 맵별 카메라 설정값(줌·오프셋·고정 영역)
├── Global/                     # 월드 전역 설정 · 공용 모델 · 게임로직
│   ├── common.gamelogic        # SlayDeckController 부착 지점 (산출물)
│   ├── DefaultPlayer.model     # 플레이어 모델 (턴전투용 이동 정지 freeze 적용)
│   ├── ChaseMonster.model · MoveMonster.model   # 몬스터 공용 모델
│   ├── SectorConfig.config     # 섹터/맵 등록 (lobby + map01~05 = 6 entries)
│   ├── WorldConfig.config      # 월드 설정
│   └── ...
├── RootDesk/
│   └── MyDesk/                 # 작업용 책상 — codeblock(스크립트)·타일셋
│       ├── SlayDeckController.codeblock  # 게임 전체 컨트롤러 (★산출물, 직접 편집 금지)
│       ├── Monster.codeblock · MonsterAttack.codeblock   # 필드 액션 몬스터 (카드 전투와 별개)
│       ├── PlayerAttack.codeblock · PlayerHit.codeblock · UIPopup.codeblock · UIToast.codeblock
│       ├── CombatMonster.codeblock   # 맵 몬스터 EnemyId 마커 + /common 자기등록
│       ├── MapCamera.codeblock       # 맵별 카메라 적용
│       ├── PlayerLock.codeblock      # 전투맵 플레이어 입력·이동 잠금
│       ├── LobbyNpc.codeblock        # 로비 NPC 상호작용(근접·클릭)
│       └── LobbyMobility.codeblock   # 로비 이동·공격 해제 + 카메라 추종
├── map/                         # 맵 6종 (산출물)
│   ├── lobby.map               # 로비 허브 맵 (마을 배경, NPC 4종, 전투 없음)
│   └── map01.map ~ map05.map   # 5막 전투/맵 노드 (공식 배경 + STS풍 우측 배치)
├── tools/                       # 결정적 생성기·도구 (주체별 폴더, 단일 소스)
│   ├── deck/                    # gen-slaydeck.mjs(★게임 전체 생성: 카드/덱·전투·맵노드·상점·유물·로비·메뉴 UI + SlayDeckController + common) · gen-cardhand.mjs
│   ├── map/                     # gen-maps.mjs(맵 배경/타일) · gen-lobby-map.mjs(로비 맵+NPC) · gen-map-encounters.mjs(노드별 몬스터 그룹) · rogue-map.mjs(절차 생성 JS 미러)+test
│   ├── camera/                  # gen-camera.mjs(맵별 고정 카메라 codeblock)
│   ├── player/                  # gen-player-lock.mjs(전투맵 입력 잠금) · freeze-turn-player.mjs(모델 이동 정지) · gen-lobby-npc.mjs(LobbyNpc·LobbyMobility codeblock)
│   ├── monster/                 # gen-combat-monster.mjs(EnemyId 마커) · freeze-turn-monsters.mjs(필드 AI 정지)
│   ├── balance/                 # sim-balance.mjs(전투 밸런스 몬테카를로 시뮬) · sim-balance.test.mjs
│   ├── verify/                  # count.mjs·uimap.mjs·cbgap.mjs(산출물 카운트/UIGroup 매핑/재연결 GAP 검증 — 경로 내장)
│   └── git/                     # gitea-pr.mjs(UTF-8 안전 PR 생성/수정/머지 — RULES.md 참조)
├── ui/                         # UIGroup 7종 — 메이커 저작(Default/Select/Lobby/Run/Deck/Popup/Toast)
├── docs/
│   ├── slaymaple_basic_framework.md     # 전투 프레임워크 설계 문서
│   ├── ui-generation-structure.md       # UI 생성 구조 문서
│   └── superpowers/specs|plans/         # 각 기능 설계·구현 계획 문서(P1~P15)
├── RULES.md                    # 협업·AI 에이전트 하네스 규칙 (토큰 가드·검증·PR 절차)
├── CLAUDE.md                   # Claude Code 자동 로드 (RULES.md 임포트)
└── README.md

⚠️ map/*.map · SlayDeckController.codeblock · Global/common.gamelogic는 생성 산출물입니다 — 직접 편집하면 재생성 때 사라집니다. 게임 로직 변경은 data/*.json·tools/의 생성기를 고쳐 재생성하세요. ui/*.ui는 메이커 저작(생성기 미생성)이라 메이커에서만 편집합니다(자세한 규칙은 RULES.md). .mcp.json, .codex/Authorization 토큰이 포함되어 있어 git에서 제외됩니다(.gitignore). 각자 로컬에서 직접 구성하세요.


직업 컨셉

3직업 모두 Slay the Spire 2 차용 + 메이플 IP 재해석. 카드 덱 상세 설계는 docs/deck-concept.md 참조.

  • ⚔️ 전사 (탱커, Ironclad 차용)파이터: 공격을 연속으로 내면 콤보가 쌓이고(방어·파워 등 비공격 카드를 쓰면 콤보 리셋) 콤보로 데미지 증가 버프 = 브루저. 페이지: 위협 디버프로 버티며 방어도 축적 → 바디 슬램(방어 비례 피해) 카운터. 스피어맨: 하이퍼바디·아이언월 유지/리치형.
  • 🗡️ 도적 (단검·독, Silent 차용) — 표창 난사 / 독 / 교활·버림. 어쌔신(표창·크리·흡혈) / 시프(단검 난타·독). 형 구현 완료(Silent 88장).
  • 🔮 법사 (약체·게이지, Defect 차용)위자드(불/독): 독을 묻히고 독 걸린 적에 불 카드 → 추가 데미지(독뎀 시너지). 위자드(썬/콜): 오브로 썬더(다중 공격)·콜드(빙결=취약+피해), 오브 획득·다중 소모 운용. 클레릭: 오브 없이 회복·버프 + 언데드엔 힐로 공격하는 보조 힐러.

게임 프레임워크 현황

StS2풍 덱빌더 로그라이크가 end-to-end로 완성됐고, 이제 로비 마을을 기점으로 반복 런이 돕니다:

로비 맵(NPC 4종) → 모험가 NPC → 캐릭터 선택(전사/도적/마법사) → 절차 생성 맵(5막)
   → 전투/엘리트/상점/휴식/유물 방 → 보상·전직·덱 성장 → 보스 → 다음 막
   → 런 클리어(승천 해금) → 로비 복귀(영혼 정산) → 다음 런 …

게임 전체는 /common 엔티티에 부착된 SlayDeckController 단일 컴포넌트로 동작합니다. UI는 메이커 저작(7개 UIGroup: Default/Select/Lobby/Run/Deck/Popup/Toast)이고, 컨트롤러가 엔티티 경로(/ui/<UIGroup>/<Hud>/...)로 내용을 런타임 주입합니다. 생성기 tools/deck/gen-slaydeck.mjsSlayDeckController.codeblock + common.gamelogic만 생성(.ui 미접근, 결정적 출력 — RULES.md 참조). 게임 데이터는 data/*.json, 맵 구조는 런타임 절차 생성(GenerateMap Lua ↔ tools/map/rogue-map.mjs JS 미러).

구현된 기능 (배포 퀄리티 P1P15, PR #34#57)

영역 내용
로비 마을 전용 물리 맵 lobby.map(마을 배경). NPC 4종 월드 엔티티 — 모험가(런 시작)·사서(카드 도감)·상인(영혼 상점)·안내원(게시판). 근접 시 머리 위 마크 + 또는 직접 클릭으로 상호작용. 이동·공격 모션은 로비 맵에서만 풀림(전투맵은 잠금), 카메라는 로비에서 플레이어 추종(전투맵은 고정)
캐릭터·전직 시작 시 전사(HP80)/도적(HP70)/마법사(HP70) 3종 선택, 클래스별 시작 덱. 보스 클리어 시 [유물] vs [2차 전직] — 각 클래스 3종(전사→파이터/페이지/스피어맨, 법사→위자드불독/위자드썬콜/클레릭, 도적→Shiv/Poison/Trickster). 전용 카드는 해당 클래스 풀만 획득
카드 전투 에너지 3·드로우·드래그 사용(공격=적에 드롭, 스킬=위로 스윕). 카드 122장 — kind Attack/Skill/Power/Status. 메커니즘: 다단히트·방어 무시·자가 디버프·드로·회복·전체 공격(AoE)·독(DoT)·retain(턴 종료 손패 유지)·sly discard(버림 트리거)
버프/디버프 StS 표준 — (+N 영구)·약화(주는 피해 25%)·취약(받는 피해 +50%)·(매 행동 틱). 양방향(적 디버프 인텐트 포함), 인텐트는 최종 예상치 표시
전투 연출 공격 이펙트·몬스터 데미지 팝업(자릿수 스킨)·드래그 타깃 마커·적 개별 차례·공격/피격/독뎀 모션(아바타 상태 전이·몬스터 hit 클립·런지/넉백)
절차 생성 맵 막 시작마다 경로 생성(런마다 다름, 가로 진행). 층 규칙: 12층 전투만 → 3층 상점/휴식 → 4층~ 엘리트/유물 방 → 보스 수렴. 점선 경로·상태 4단·층 카운터. 노드 타입별 몬스터 랜덤 구성(일반 1~3 / 엘리트 / 보스) + intent 랜덤 행동
유물 19종 / 물약 6종 유물: StS 효과 × 메이플 장비 외형, TopBar 아이콘 + 마우스오버 툴팁, 8종 훅. 물약: 승리 40% 드랍·상점·슬롯 메뉴. 보물 방=상자 연출 → 유물+메소
카드 프레임·등급 커스텀 프레임 3종(전사/마법사/도적 × normal/unique/legend), 카드 5개 사이트 통합 레이아웃. 보상 등급 가중 추첨 70/25/5
영혼(Soul) 메타 성장 승천과 별개의 영구 강화 화폐. 2차 전직 상태로 보스 클리어 시 적립 → 로비 영혼 상점 4종 해금(시작 메소 +60·HP +15·덱 정제·시작 유물 +1). UserDataStorage 영구 저장
승천(Ascension) A1~A10 누적 모디파이어(적 강화·시작 HP 감소·보상 감소). UserDataStorage 유저별 영구 저장, 런 클리어 시 다음 단계 해금
멀티 act 5막 진행(보스 클리어→다음 막 텔레포트, 맵·인카운터 변경, 적 스케일 1+(막-1)*0.45), 5막 클리어 시 런 종료
경제 화폐 표기 메소(코인 아이콘), 카드/유물/물약 메소 가격. 내부 식별자는 Gold 유지
밸런스 시뮬 tools/balance/sim-balance.mjs — 전투 규칙 JS 미러(몬테카를로) + tools/map/rogue-map.mjs(맵 생성 미러) + node 단위테스트

⚠️ 수치(적 스탯·경제·승천 배율)는 1차 조정 상태입니다. 정밀 밸런싱은 sim-balance.mjs로 검증하며 진행합니다. 도적(Silent) 카드 88장은 STS Silent 완역 포트 + 공식 스킬 아이콘 적용 완료(PR #73). 남은 작업은 카드명 메이플 재서사(어쌔신/시프)·멀티플레이어 전제 카드 싱글 정리 — docs/deck-concept.md 참조.

유용한 스크립트 호출

/common 엔티티(또는 Play Test 컨텍스트)에서:

local c = _EntityService:GetEntityByPath("/common").SlayDeckController
-- 로비
c:OnLobbyNpcInteract("run")    -- 모험가(런 시작) / "codex"(도감) / "shop"(영혼상점) / "board"(게시판)
c:ShowLobby()                  -- 로비 맵 복귀 + 상태 초기화
-- 런
c:SelectClass("warrior")       -- "warrior" / "bandit" / "magician"
c:StartNewGame()               -- 캐릭터 선택 → 런 시작(map01 텔레포트)
c:PickNode("r1c2")             -- 맵 노드 선택(절차 생성 그리드 id) / "boss"
c:PlayCard(1)                  -- 손패 slot 카드 사용
c:EndPlayerTurn()              -- 턴 종료 → 적 턴 → 다음 턴
c:PickReward(1)                -- 보상 카드 1택(0=건너뛰기)
c:BuyCard(1) / c:BuyRelic() / c:BuyPotion()   -- 상점 구매(메소)
c:SetJob("fighter")            -- 전직 (보스 보상 선택 화면)
c:AdjustAscension(1)           -- 메뉴에서 승천 단계 +1

밸런스 검증: node tools/balance/sim-balance.mjs [N] [--seed S] · 테스트: node --test tools/balance/sim-balance.test.mjs tools/map/rogue-map.test.mjs. 상세 설계는 docs/slaymaple_basic_framework.mddocs/superpowers/specs/ 참조.

디버그 단축키

개발·QA용 키보드 단축키. 전투 중(런 활성 + 전투 진행 중)에만 동작합니다.

단축키 기능
Ctrl + Shift + C 카드 picker — 직업 전체 카드 패널을 띄우고, 카드를 클릭하면 즉시 손패에 추가. 상단 탭(전사/도적/마법사)으로 직업별 카드 풀 전환. 카드 효과·메커니즘 즉석 테스트용
Ctrl + Shift + E 전체 회복 치트 — 체력·에너지를 최대치로 회복

카드 picker는 메이커 저작 UI DeckUIGroup/DeckAllHud(120 슬롯 그리드 + 직업 탭 3종)를 사용하고, 컨트롤러가 런타임에 카드 비주얼·버튼을 바인딩합니다. 구현: 키 바인딩 tools/deck/cb/boot.mjs, picker 로직 tools/deck/cb/deckview.mjs(OpenDebugCardPicker/OnAllDeckCardButton), 버튼 바인딩 tools/deck/cb/deckturn.mjs(BindButtons). 옛 picker UI 생성기 tools/deck/legacy/hud/deckall.mjs는 UI 메이커-저작 전환 후 휴면(Maker UI가 대체).

산출물 재생성

node tools/deck/gen-slaydeck.mjs        # 컨트롤러+common (UI는 메이커 저작 — 미생성)
node tools/map/gen-maps.mjs             # map01~05 배경/타일
node tools/map/gen-lobby-map.mjs        # 로비 맵 + NPC 배치
node tools/player/gen-lobby-npc.mjs     # 로비 codeblock(LobbyNpc·LobbyMobility)
node tools/camera/gen-camera.mjs        # 맵별 카메라
node tools/player/gen-player-lock.mjs   # 전투맵 입력 잠금
node tools/monster/gen-combat-monster.mjs   # 몬스터 EnemyId 마커

산출물 검증은 내용 출력 없이 카운트만: node tools/verify/count.mjs <ui|cb|common> <regex>... (자세한 가드는 RULES.md).


아키텍처 메모

현재 게임 전체 로직이 SlayDeckController 단일 codeblock에 모여 있습니다. 초기 설계의 3분할(SlayCardCatalog/SlayRunState/SlayCombatManager)은 기능적으로 모두 구현됐으나 아직 한 컴포넌트 안에 있습니다. 맵 NPC·카메라·입력 잠금 등 맵 단위 동작은 별도 codeblock(LobbyNpc/LobbyMobility/MapCamera/PlayerLock/CombatMonster)으로 분리해 각 맵 루트/엔티티에 부착합니다. 카드/적/맵/유물/프레임/카메라 데이터는 data/*.json로 외부화돼 있습니다. 2026-06-17: UI를 단일 DefaultGroup에서 7개 UIGroup(Select/Lobby/Run/Deck 등)으로 분리해 메이커 저작으로 전환 — 생성기는 더 이상 .ui를 만들지 않고, 컨트롤러가 새 UIGroup 경로로 재연결됨(옛 UI emit hud/*·gen-cardhandtools/deck/legacy/ 휴면). 재연결 무결성은 tools/verify/cbgap.mjs(GAP 0)로 검증.

⚠️ 전투 규칙과 맵 생성은 Lua(gen-slaydeck 내장)와 JS 미러(sim-balance/rogue-map)로 이중 구현입니다. 한쪽을 고치면 반드시 다른 쪽도 동기화하고 테스트하세요(RULES.md §6).


향후 개선 계획 (후속 후보)

  • 전투 루프 · 런 루프 · 절차 생성 맵 · 상점/휴식/유물 방 · 유물 19종 · 물약 · 버프/디버프 · Power · 전직(전사/법사/도적 2차) · 승천+개인 저장 · 전투 모션 · 커스텀 프레임 · 반복 런·로비 맵·NPC·영혼·메소·카메라 추종 (P1~P15 완료)
  • UI 메이커-저작 전환 — 단일 DefaultGroup → 7개 UIGroup 분리, 생성기 UI 저작 폐기(tools/deck/legacy/), 컨트롤러 경로 재연결(cbgap GAP 0), MainMenu→로비→run NPC→charselect 부트 흐름 (2026-06-17)
  • 도적 카드 아이콘 — Silent 88장에 실 스킬 아이콘(image/fx) 할당, 2차 전직 설명 한글화
  • 런 이어하기 — 진행 중 런 직렬화 저장(UserDataStorage 확장, 메뉴 "이어하기" 활성화)
  • 카드 제거/업그레이드 — 상점 카드 제거 슬롯, 휴식 노드에서 카드 강화
  • 이벤트 노드(?) — 랜덤 텍스트 이벤트(선택지·리스크/리워드)
  • 3차 전직 — 후반 막 보상으로 확장
  • 궁수 등 추가 클래스 — 캐릭터 선택 슬롯 확장
  • 정밀 밸런싱 — 첫 인카운터 승률 완화·직업별 카드 효율 튜닝(sim-balance.mjs 리포트 기반)
  • 상점 보장 규칙 — 막당 상점 최소 1회 등장
  • 연출 보강 — 사운드(타격·획득), 맵 화면에 유물/물약 표시

신규 참여자 셋업

  1. 저장소 클론
    git clone https://gitea.gahusb.synology.me/gahusb/maplecontest.git slaymaple
    
  2. MSW Maker에서 이 폴더를 로컬 워크스페이스 경로로 지정해 월드 열기
  3. .mcp.json / .codex/ 는 git에 없으므로, 본인 토큰으로 직접 생성 (MCP·Codex 사용 시)
  4. 작업 전 항상 git pull + 메이커 reload, 작업 후 git add/commit/push
  5. AI 에이전트(Claude Code 등)로 작업한다면 RULES.md 필독 — 생성 산출물 접근 금지(토큰 가드)·검증 절차·PR 도구(tools/git/gitea-pr.mjs) 규칙. Claude Code는 CLAUDE.md가 자동 적용
Description
No description provided
Readme 31 MiB
Languages
JavaScript 95.9%
PowerShell 4%