Files
maplecontest/docs/superpowers/specs/2026-06-13-p14-loop-lobby-soul-design.md
2026-06-14 00:03:13 +09:00

7.8 KiB

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. 몬스터 랜덤성: 구성(일반 13 / 엘리트 1+일반 02 / 보스 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: 전 카드 도감(클래스별 그리드). OnBeginPlayShowLobby(메뉴 대체), EndRunShowLobby. 첫 실행/패배/클리어 모두 로비 기점.

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로 공존.