Files
maplecontest/docs/superpowers/specs/2026-06-09-run-loop-core-design.md
2026-06-09 02:27:38 +09:00

4.1 KiB

런 루프 코어 (TODO E1+E2) — 설계

작성: 2026-06-09 / 상태: 승인됨 / 근거: TODO.md 항목 E(분해) + SlayDeckController 분석. E(로그라이크 메타)의 첫 하위 프로젝트. 선행: B·D 완료. 후속: E3(맵)·E4(상점)·E5(유물)·E6(보스/저장).

문제

단일 전투(B)는 닫혔으나 승리 후 보상·다음 전투·덱 성장이 없다(보상 훅 자리만 비어 있음). 전투를 한 "런"으로 확장해야 덱빌딩 로그라이크가 된다.

범위 (이 슬라이스)

전투를 연속 N전투 런으로 확장: 런 상태 영속(HP/골드/덱) + 승리 후 카드 1택 보상 + 다음 전투 연결 + 고정 N전투 후 "런 클리어". 맵 노드·상점·유물·보스·저장은 범위 밖(후속 E3~E6). 아키텍처: 기존 SlayDeckController 확장(별도 RunState 분리는 후속).

설계

런 파라미터 (생성기 상수 — 향후 외부화)

  • RUN_LENGTH = 3 (런당 전투 수), GOLD_PER_WIN = 15.

새 상태 (SlayDeckController 속성)

  • RunDeck(any) — 보유 카드 id 누적 배열(영속).
  • Gold(number) — 누적 골드.
  • Floor(number) — 현재 전투 번호(1-base).
  • RunLength(number) — 런당 전투 수.
  • RewardChoices(any) — 현재 제시 중인 보상 카드 id 3개.
  • RunActive(boolean) — 런 진행 중.
  • 플레이어 HP는 전투 간 유지(StartCombat에서 리셋 안 함).

메서드

  • OnBeginPlayself:StartRun().
  • StartRun(신규): PlayerMaxHp=80, PlayerHp=PlayerMaxHp, Gold=0, Floor=0, RunLength=RUN_LENGTH, RunDeck = starterDeck 복사, RunActive=trueBindButtons()(1회) → StartCombat().
  • StartCombat(수정): Floor += 1; 적 데이터(activeEnemy) 세팅; 전투별 리셋(Energy/Turn/Block/ EnemyHp/EnemyBlock/EnemyIntentIndex/DiscardPile/Hand/CombatOver); DrawPile = RunDeck 복사 → Shuffle; Cards 테이블 세팅. HP·Gold·RunDeck 보존, BindButtons 호출 제거. → RenderCombat → StartPlayerTurn.
  • BindButtons(수정): EndTurn·카드5·보상카드3·건너뛰기 버튼을 1회 바인딩(StartRun에서 호출).
  • CheckCombatEnd(수정):
    • 적 HP≤0(승리): Gold += GOLD_PER_WIN; CombatOver=true; Floor >= RunLength이면 ShowResult("런 클리어!") + RunActive=false; 아니면 self:OfferReward().
    • 플레이어 HP≤0(패배): CombatOver=true; ShowResult("패배..."); RunActive=false.
  • OfferReward(신규): RewardChoices = 카드풀에서 3개 무작위(math.random); 각 보상 카드 UI 갱신 (이름/코스트/설명/색); RewardHud 표시(Enable).
  • PickReward(slot)(신규): slot(1~3)이면 RewardChoices[slot]RunDeck에 추가; slot=0(건너뛰기)이면 추가 안 함; RewardHud 숨김 → StartCombat()(다음 층).
  • RenderRun(신규): 층 Floor/RunLength·골드 Gold 텍스트 갱신. RenderCombat에서 호출.

UI (생성기 신규)

  • RewardHud(평소 숨김): 제목 "보상 카드 선택" + 보상 카드 3장(UISprite+버튼, 이름/코스트/설명 자식) + "건너뛰기" 버튼.
  • HUD 표시 추가: /ui/DefaultGroup/CombatHud/Floor("층 1/3"), /Gold("골드 0").
  • 보상 카드 클릭 → PickReward(slot), 건너뛰기 → PickReward(0).

버그 예방

  • BindButtons가 매 전투(StartCombat)마다 카드 버튼에 ConnectEvent → 런에서 핸들러 중첩. StartRun에서 1회만 바인딩으로 이동(StartCombat의 BindButtons 호출 제거).

검증 (메이커 Play)

  • 전투 승리 → RewardHud에 카드 3장 표시; 골드 +15·층 표시.
  • 보상 1택 → RunDeck +1(다음 전투 손패/덱에 등장 가능), RewardHud 숨김, 다음 전투 시작(HP 유지).
  • 건너뛰기 → 덱 변화 없이 다음 전투.
  • 3전투째 승리 → "런 클리어!"·런 종료. 도중 패배 → "패배..."·런 종료.
  • 카드/보상 버튼 클릭은 런타임(MCP는 PlayCard/EndPlayerTurn/PickReward 직접 호출로 검증).
  • 생성기 결정적, JSON 유효.

범위 밖 (금지)

  • 맵 노드(E3)·상점/휴식(E4)·유물(E5)·보스/층전환/저장(E6). 골드 소비(E4). 보상 풀 확장(메이플 IP 추후).