diff --git a/docs/superpowers/plans/2026-06-11-system-gaps.md b/docs/superpowers/plans/2026-06-11-system-gaps.md new file mode 100644 index 0000000..655824d --- /dev/null +++ b/docs/superpowers/plans/2026-06-11-system-gaps.md @@ -0,0 +1,79 @@ +# 시스템 갭 보완 (P5) 구현 계획 + +> **For agentic workers:** REQUIRED SUB-SKILL: superpowers:subagent-driven-development. T3·T5는 컨트롤러 직접. + +**Goal:** 경제 밸런스(첫 상점 구매 가능), 신규 카드 2종+복합 효과, 적 패턴 보강, 런 종료 후 메뉴 복귀. + +--- + +## Task 1: 데이터+상수 (경제·적 패턴·신규 카드 골격) + +**Files:** `data/enemies.json`, `data/cards.json`, `tools/deck/gen-slaydeck.mjs`(상수·elite 골드) + +- [ ] enemies.json 의도 패턴 교체(스펙 §2.C 표 그대로; slime 3종·king_slime 유지). +- [ ] cards.json에 추가(이미지는 T3에서 채움 — 일단 필드 생략): +```json + "WarLeap": { "name": "워 리프", "cost": 1, "kind": "Attack", "damage": 4, "block": 3, "desc": "피해 4, 방어도 3" }, + "Brandish": { "name": "브랜디시", "cost": 2, "kind": "Attack", "damage": 13, "desc": "피해 13" } +``` +- [ ] gen-slaydeck: `GOLD_PER_WIN = 15` → `25`; CheckCombatEnd elite 분기(AddRelic 줄 옆)에 `self.Gold = self.Gold + 15` 추가. +- [ ] 검증: JSON 파스, gen-slaydeck 실행 OK(산출물 복원), sim 통과(기존 fixture 무관). +- [ ] Commit: `feat(system-gaps): 경제 상향(승리25·엘리트+15)·적 패턴 보강·신규 카드 2종 데이터` + +## Task 2: 복합 카드 로직 + EndRun 복귀 + sim + +**Files:** `tools/deck/gen-slaydeck.mjs`, `tools/balance/sim-balance.mjs`, `tools/balance/sim-balance.test.mjs` + +- [ ] **sim 테스트 먼저** (test 파일에 추가): +```js +test('simulateCombat: Attack 카드의 block 필드도 적용(복합 카드)', () => { + const data = { + cards: { Combo: { name: '콤보', cost: 1, kind: 'Attack', damage: 4, block: 3 } }, + starterDeck: ['Combo', 'Combo', 'Combo', 'Combo', 'Combo'], + monsters: [{ name: '적', maxHp: 9, intents: [{ kind: 'Attack', value: 5 }] }], + }; + const r = simulateCombat(data, mulberry32(1)); + assert.equal(r.win, true); // 3코스트 내 3장: 12딤>9 → 1턴 승리(블록 적용 여부와 무관하게 승리하지만) + assert.equal(r.playerHpRemaining, 80); // 피해 받기 전 승리 — 블록 검증은 아래 시나리오로 +}); +test('simulateCombat: 복합 카드 블록이 적 공격을 흡수', () => { + const data = { + cards: { Combo: { name: '콤보', cost: 1, kind: 'Attack', damage: 1, block: 3 } }, + starterDeck: ['Combo', 'Combo', 'Combo', 'Combo', 'Combo'], + monsters: [{ name: '적', maxHp: 100, intents: [{ kind: 'Attack', value: 9 }] }], + }; + const r = simulateCombat(data, mulberry32(1)); + // 1턴: 3장 사용 → 블록 9 → 적 공격 9 전부 흡수 → 2턴 시작 HP 80 유지 확인 위해 2턴 후 비교 불가(루프) — 간접: MAX_TURNS 도달 draw, hp가 (80 - 0*몇턴)... + // 단순 명제: 블록 미적용이면 매턴 -9 → 100/9≈11턴 내 사망. 블록 적용이면 매턴 9블록=무피해 → draw. + assert.equal(r.draw, true); + assert.equal(r.playerHpRemaining, 80); +}); +``` +- [ ] sim 구현: simulateCombat Attack 분기에 `if (c.block) pBlock += c.block;` 추가(스탯 bump의 block 합산도 `c.block || 0`로). 테스트 통과. +- [ ] gen-slaydeck PlayCard Attack 분기에 추가(PlayAttackFx 호출 다음 줄): +``` + if c.block ~= nil then + self.PlayerBlock = self.PlayerBlock + c.block + end +``` +- [ ] gen-slaydeck EndRun: 신규 메서드 + CheckCombatEnd 두 지점 교체: +```js + method('EndRun', `self:ShowResult(text) +self.RunActive = false +_TimerService:SetTimerOnce(function() self:ShowMainMenu() end, 4)`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'text' }]), +``` +교체: `self:ShowResult("런 클리어!")` + `self.RunActive = false` → `self:EndRun("런 클리어!")`; `self:ShowResult("패배...")` + `self.RunActive = false` → `self:EndRun("패배...")`. +- [ ] 검증: sim 전체 통과(16개), gen 실행·심볼 확인 후 산출물 복원. +- [ ] Commit: `feat(system-gaps): 복합 카드(피해+방어)·런 종료 후 메뉴 복귀(EndRun)` + +## Task 3 (컨트롤러 직접): 신규 카드 이미지 수확 +- "워 리프"/"브랜디시" 검색→메이커 선별→cards.json image 채움→커밋. + +## Task 4: 재생성·검증·산출물 커밋 (T3 이후) +- 표준 절차 + `node tools/balance/sim-balance.mjs 2000` 결과 기록(참고). + +## Task 5 (컨트롤러 직접): 메이커 검증+푸시+PR+머지 +- 보상/상점 신규 카드(이미지)·복합 카드 효과·엘리트 골드·패배→4s 메뉴 복귀. 스크린샷. + +## Self-Review +- §2.A→T1, §2.B→T1(데이터)+T2(로직)+T3(이미지), §2.C→T1, §2.D→T2. 시그니처 일관(EndRun(text)). 복합 카드 sim 테스트는 블록 적용을 draw/hp로 결정적으로 판별. diff --git a/docs/superpowers/specs/2026-06-11-system-gaps-design.md b/docs/superpowers/specs/2026-06-11-system-gaps-design.md new file mode 100644 index 0000000..069c9e9 --- /dev/null +++ b/docs/superpowers/specs/2026-06-11-system-gaps-design.md @@ -0,0 +1,53 @@ +# 시스템 갭 보완 (P5) — 설계 + +- 날짜: 2026-06-11 +- 상태: 승인됨(사용자 사전 위임). 로드맵 P5/5 (선별 범위). + +## 1. 선별 항목 (임팩트/리스크 기준) + +| # | 항목 | 문제 | 해결 | +|---|---|---|---| +| A | 경제 밸런스 | 골드/승리 15 < 카드 30 → 첫 상점 구매 불가 | `GOLD_PER_WIN` 15→25, 엘리트 승리 보너스 골드 +15(유물에 더해) | +| B | 카드 풀 | 3종뿐 — 보상/상점 단조 | 신규 2종 + **복합 효과(damage+block 동시) 지원** | +| C | 적 패턴 | 신규 몬스터 의도 2~3스텝 단조 | enemies.json 패턴 보강(3~4스텝, 강공 텔레그래프) | +| D | 런 루프 미완결 | 클리어/패배 후 Result 텍스트만(메뉴 복귀 없음) | 결과 표시 4s 후 `ShowMainMenu` 자동 복귀 | + +범위 제외: 저장(E6b 사용자 보류), 카드 제거/업그레이드/포션/이벤트 노드(후속). + +## 2. 설계 + +### 2.A 경제 +- `GOLD_PER_WIN = 25` (gen-slaydeck 상수). +- `CheckCombatEnd` elite 분기에 `self.Gold = self.Gold + 15` 추가(유물 지급 유지). + +### 2.B 복합 카드 +- 규칙 확장: **Attack 카드에 block 필드가 있으면 방어도 함께 적용** (Skill은 기존대로 block만). + - Lua `PlayCard`: Attack 분기에서 `if c.block ~= nil then self.PlayerBlock = self.PlayerBlock + c.block end` 추가(데미지는 기존 PlayAttackFx 경로). + - sim `simulateCombat`: Attack 분기에 동일 추가 + 테스트 1종. +- 신규 카드(`data/cards.json`): + - `WarLeap`(워 리프): cost 1, Attack, damage 4, block 3, desc "피해 4, 방어도 3" — 복합. + - `Brandish`(브랜디시): cost 2, Attack, damage 13, desc "피해 13" — 고코스트 딜. + - 이미지: 공식 RUID 수확(검증된 워크플로 — "워 리프"/"브랜디시" 질의, 부적합 시 기존 보조 질의). +- 시작 덱 불변(신규 카드는 보상/상점 풀에서 등장 — 풀은 `self.Cards` 전체이므로 자동 포함). + +### 2.C 적 패턴 (enemies.json) +- orange_mushroom: [공5, 방4, 공7] → [공5, 공5, 방4, 공8] (빌드업) +- green_mushroom: [공7, 공4] → [공7, 방3, 공9] +- pig: [공6, 방3] → [공6, 공6, 방5] +- blue_mushroom: [공8, 공4] → [공4, 공4, 공10] (텔레그래프형) +- mushmom: [공14, 방10, 공9] → [방10, 공16, 공9, 방6] +- modified_snail: [공12, 공7, 방8] → [공12, 방8, 공7, 공14] +- king_slime: 유지(이미 4스텝). slime/slime_elite/slime_boss: 유지(레거시 호환). + +### 2.D 런 종료 복귀 +- `ShowResult(text)` 호출 후 `RunActive=false`가 되는 두 곳(런 클리어·패배)에서: 4초 타이머 → `self:ShowMainMenu()`. +- 구현: `ShowResult`에 두 번째 동작 추가 대신 **새 메서드 `EndRun(text)`** = ShowResult(text) + RunActive=false + 4s 타이머 ShowMainMenu. CheckCombatEnd의 두 지점("런 클리어!"/"패배...")을 EndRun 호출로 교체. +- ShowMainMenu는 ShowState("menu")로 전 HUD 정리(기존) — Result는 CombatHud 자식이라 같이 숨겨짐. 단 Result.Enable 자체는 StartCombat에서 리셋(기존). + +## 3. 검증 +- sim: 복합 카드 테스트 추가, 전체 통과. `node tools/balance/sim-balance.mjs 2000`으로 새 패턴 승률 출력(참고 기록 — 100%면 여전히 약함이나 P5 범위는 구조, 수치 정밀 튜닝은 후속). +- 메이커: 보상/상점에서 신규 카드 등장(이미지 포함), 복합 카드 사용 시 피해+방어 동시, 패배 또는 클리어 → 4s 후 메뉴 복귀, 엘리트 승리 골드 +15+25. + +## 4. 리스크 +- 복합 카드의 sim AI(chooseAction)는 Attack 우선 로직 그대로(블록 가치 미평가) — 밸런스 추정 약간 보수적, 허용. +- EndRun 타이머 중 사용자가 이미 메뉴로 못 가는 상태(입력 잠금) — CombatOver=true가 가드.