From f67471435e11016dbf3bea5602a4a8b13ae93a9e Mon Sep 17 00:00:00 2001 From: gahusb Date: Sun, 14 Jun 2026 00:03:13 +0900 Subject: [PATCH] =?UTF-8?q?docs(p14):=20=EB=B0=98=EB=B3=B5=20=EB=9F=B0?= =?UTF-8?q?=C2=B7=EB=A1=9C=EB=B9=84=C2=B7=EC=98=81=ED=98=BC=C2=B7=EB=8F=84?= =?UTF-8?q?=EC=A0=81=C2=B7=EB=AA=AC=EC=8A=A4=ED=84=B0=20=EB=9E=9C=EB=8D=A4?= =?UTF-8?q?=EC=84=B1=20=EC=84=A4=EA=B3=84=20spec?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- .../2026-06-13-p14-loop-lobby-soul-design.md | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 docs/superpowers/specs/2026-06-13-p14-loop-lobby-soul-design.md diff --git a/docs/superpowers/specs/2026-06-13-p14-loop-lobby-soul-design.md b/docs/superpowers/specs/2026-06-13-p14-loop-lobby-soul-design.md new file mode 100644 index 0000000..6bbd447 --- /dev/null +++ b/docs/superpowers/specs/2026-06-13-p14-loop-lobby-soul-design.md @@ -0,0 +1,97 @@ +# P14 — 반복 런 · 로비 · 영혼 · 도적 · 몬스터 랜덤성 설계 + +> 작성 2026-06-13. 사용자 자율 실행 지시(Phase별 커밋 → 최종 push/PR)에 따라 인터랙티브 승인 게이트 없이 +> 설계 결정을 본 문서에 기록·커밋하고 순차 구현한다. 산출물(`ui/DefaultGroup.ui`·`*.codeblock`·`*.map`· +> `*.gamelogic`)은 생성기(`tools/`)·데이터(`data/`)에서 100% 생성되므로 본 작업은 전부 소스만 수정한다(RULES.md). + +## 목표 + +기존 P1~P13 단발 런 구조를, **로비 허브를 중심으로 반복 수행하는 로그라이트 루프**로 재편하고 +도적 직업·몬스터 랜덤성·영혼 메타 성장·카드 UX를 추가한다. + +## 핵심 설계 결정 (요약) + +1. **맵 5개 + 반복 루프**: 런은 map01~map05 5막. 최종 보스 클리어 시 무한 진행이 아니라 **로비로 복귀**해 + 영혼을 정산하고 다음 런을 준비. "반복 수행이 메인"을 *로비 기점 반복 런*으로 해석. +2. **로비 = 스크린 HUD**: 게임 전체가 이미 스크린 HUD(MapHud/ShopHud/RewardHud) 구동이고 물리 맵은 배경일 뿐이다. + 로비도 동일하게 `LobbyHud`(스크린)로 구현하고, NPC는 클릭 가능한 스프라이트 버튼으로 배치한다. + NPC 4종: **도감(Codex)·상점(영혼 메타)·런 시작·게시판(채팅 대용)**. 첫 실행/패배/클리어 시 진입점. +3. **영혼(Soul)**: 승천(패널티 누적)과 역할 분리된 **영구 강화 메타 화폐**. + *2차 전직을 한 상태로* 맵 보스를 클리어할 때마다 누적. 로비 상점 NPC에서 해금 구매 → 다음 런에 이점. + 저장은 승천 RPC 패턴 복제(`UserDataStorage`, key `soulPoints`/`soulUnlocks`). +4. **도적**: `bandit` 프레임이 이미 데이터에 준비됨. 도적 1차 + 2차(어쌔신/시프) 카드·스타터덱 신규. +5. **몬스터 랜덤성**: 구성(일반 1~3 / 엘리트 1+일반 0~2 / 보스 1)과 행동(정의된 intent 중 랜덤)을 런타임 추첨. + StS2식 "덱 오염" intent(`AddCard`)와 저주 카드 신규. +6. **메소**: 표면 문자열은 이미 메소. 잔존 `goldIdol.desc` 정정 + 메소 코인 아이콘 추가(내부 식별자 `Gold`는 유지). + +## Phase 구성 (각 Phase = 1+ 커밋, 소스 수정 → 재생성 → 카운트/테스트 검증) + +### Phase 1 — 맵 5막 · depth 7 · 노드 인접 규칙 +- `gen-slaydeck.mjs`: `MAP_ROWS 7→6`(걷는행6+보스=총7), `ACT_COUNT 3→5`, `ACT_MAPS [map01..map05]`, `RUN_LENGTH 3→5`. +- 노드 타입 인접 금지 확장: 현재 elite만 부모-자식 연속 금지 → **rest·shop·elite** 3종 모두 금지. + `GenerateMap`(Lua 4333-4358) + `rogue-map.mjs`(67-72) 미러 + `rogue-map.test.mjs` 단언 추가. +- 막 배율 `1+(Floor-1)*0.6`(`:2776`)을 5막 기준 `1+(Floor-1)*0.45`로 완화. +- 맵 파일 11→5: 생성기 카운트(`gen-maps`/`gen-map-encounters`/`gen-combat-monster`/`freeze-turn-monsters`/ + `gen-camera`/`gen-player-lock`) `[2..11]→[2..5]`, `length:11→5`. `git rm map/map06..11.map`. + `Global/SectorConfig.config`에서 map06~11 엔트리 제거(생성기가 재구성하도록 보정 또는 수동 정리). + +### Phase 2 — 노드 가로 레이아웃(왼→오른쪽) +- `gen-slaydeck.mjs:1536-1538` 좌표 함수 row↔x·col↔y 스왑 + 호출부(1573/1600/1605) 인자 스왑. Lua 무수정. + 보스는 최우측 중앙. 도트 보간·간선·라벨 자동 추종. + +### Phase 3 — 몬스터 랜덤 구성 · 랜덤 행동 · AddCard · map01 배치 +- `data/enemies.json`: 종별 `tier`(normal/elite/boss) 추가, 일부 종에 `AddCard` intent 추가. + map01용 일반 5종 + 엘리트 1종 보장(slime/orange/blue/green mushroom/pig + mushmom 등 기존 활용). +- `data/cards.json`: 저주/상태 카드 신규(`kind:"Status"`, `unplayable:true`, `curse:true`, `endTurnDamage?`). +- `gen-slaydeck.mjs`: `BuildMonsters`(2780) 노드타입별 랜덤 구성, `EnemyActStep`(3603) 랜덤 intent 선택 + (예고=확정: 턴 종료 시 다음 행동 추첨 저장), `AddCard` intent 처리, `PlayCard` unplayable 가드, + 카드 직렬화(`luaCardsTable`)에 신규 필드, intent 직렬화(`luaIntentsArray`)에 `card`/`count`. +- `sim-balance.mjs`+test: 랜덤 행동(rng)·AddCard 미러, 결정성 테스트 유지, 저주 unplayable 필터. +- `gen-map-encounters.mjs`: map01 편입 + 일반5/엘리트1 레이아웃(오른쪽 배치). 엘리트 맵에 일반 혼합용 변형 배치. + +### Phase 4 — 도적 클래스 + 2차(어쌔신/시프) +- `data/cards.json`: 도적 1차(class `thief`) + 어쌔신(class `assassin`) + 시프(class `bandit`) 카드 + 스타터덱. +- `data/cardframes.json`: `classToFrame`에 thief/assassin/bandit → `bandit` 프레임 매핑. +- `gen-slaydeck.mjs`: `CLASSES.thief`(maxHp 75), `JOBS.thief`(어쌔신/시프), CharacterSelectHud Thief 해금, + `BindMenuButtons` ThiefButton, `RenderCharacterSelect`/`StartNewGame`/`StartRun`/`JobLabel` 도적 분기. +- 전사/법사 2차는 완비 확인됨(수정 불요). + +### Phase 5 — 카드 스킬 아이콘 · 피격 이펙트 분리 +- `data/cards.json`: 공격 카드에 `fx`(이펙트 RUID) 필드 추가, `image`는 스킬 아이콘 유지. +- `gen-slaydeck.mjs`: `luaCardsTable` fx 직렬화, `PlayCard`(3296-3298) FX 인자를 `c.fx or c.image`로. +- RUID는 MSW 공식 리소스 asset 검색으로 수급(계정 업로드 금지·RULES §5). + +### Phase 6 — 카드 UX: 핸드 최대 10 · 마우스오버 확대/툴팁 +- `gen-slaydeck.mjs`: CardHand 슬롯 5→10 확장, `RenderHand` 동적 간격(장수 비례), `DrawCards` 10장 상한 + (초과 분 자동 버림), 카드 hover 이벤트 바인딩(enter→`ShowTooltip`+스케일업, exit→복귀), 드래그 중 가드. +- `sim-balance.mjs`+test: 드로우 상한 미러. + +### Phase 7 — 메소 전환 + 메소 아이콘 +- `data/relics.json`: `goldIdol.desc` "골드"→"메소". +- `gen-slaydeck.mjs`: TopBar·ShopHud 메소 텍스트 옆 코인 아이콘 sprite 추가(공식 RUID). + +### Phase 8 — 로비 + NPC + 반복 루프 +- `gen-slaydeck.mjs`: `LobbyHud` 섹션(배경 + NPC 4종 스프라이트 버튼), `ShowLobby`/`ShowState("lobby")`, + NPC 핸들러(Codex→CodexHud, Shop→영혼상점, RunStart→CharacterSelect, Board→게시판 패널). + `CodexHud`: 전 카드 도감(클래스별 그리드). `OnBeginPlay`→`ShowLobby`(메뉴 대체), `EndRun`→`ShowLobby`. + 첫 실행/패배/클리어 모두 로비 기점. + +### Phase 9 — 영혼(Soul) 시스템 +- `gen-slaydeck.mjs`: `SoulPoints`/`SoulUnlocks` 프로퍼티, RPC `ReqLoadSouls`/`SaveSouls`/`RecvSouls`(ExecSpace 5/6), + 보스 클리어 & `PlayerJob~=""`일 때 영혼 가산(`ContinueAfterBoss`/`CheckCombatEnd`), 로비 영혼 상점 UI·구매, + 해금 효과를 `StartRun`에 적용(시작 메소/시작 유물/시작 HP/덱 강화 등 덱빌딩 이점). + +### Final — 전체 재생성 · 테스트 · push · PR +- 전 생성기 재생성, `node --test`(rogue-map·sim-balance), 카운트 검증, 가능 시 메이커 플레이테스트. +- `tools/git/gitea-pr.mjs`로 UTF-8 spec JSON 작성 후 PR 생성(RULES §4). + +## 검증 원칙 (RULES §2·§6) +- 산출물 본문 출력 금지 — `grep -c`/JSON parse/카운트만. +- 전투·맵 규칙 수정 시 Lua↔JS 미러 동시 수정 + `node --test` 통과. +- 커밋은 기능 단위, 산출물 재생성은 메시지에 명시. + +## 알려진 제약 / 결정 근거 +- **로비 "돌아다니기"**: 물리 맵 walkable 로비는 player 이동이 전역 freeze(턴제)라 위험·고비용 → 스크린 HUD + NPC 클릭으로 동일 기능 제공(아키텍처 정합). 추후 walkable 로비는 확장 슬롯. +- **카드 아이콘/이펙트**: 현재 `c.image`가 카드 아트 겸 피격 FX로 이중 사용 중 → `fx` 분리로 의도 달성. +- **영혼 vs 승천**: 승천=적 강화 패널티 토글, 영혼=플레이어 영구 강화 → 같은 저장소 다른 key로 공존.