Files
maplecontest/docs/superpowers/specs/2026-06-12-buffs-power-design.md
2026-06-12 01:12:57 +09:00

108 lines
5.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# P6 — 버프/디버프·Power 카드·적 방어도 UI 설계
날짜: 2026-06-12
브랜치: `feature/p6-buffs-power`
근거: 덱빌딩 코어 확장 — Slay the Spire 2의 약화·취약·힘 시스템과 Power 카드 종류를 메이플 IP로 이식. 적 방어도 미표시 문제 해결.
## 범위
1. **버프/디버프 3종** — 약화(Weak)·취약(Vulnerable)·힘(Strength), StS 표준 수치
2. **Power 카드 kind** — 전투 동안 지속되는 효과, 사용 시 소멸(전투 한정)
3. **적 방어도 UI** — 적 슬롯에 플레이어와 동일한 방어도 배지 표시
4. **예시 카드 4종** — 메이플 스킬명, StS 카드 효과 매핑
5. **적 디버프 인텐트** — 일부 적이 플레이어에게 약화/취약 부여 (양방향 시스템)
비범위: 물약·유물 강화(P7), 카드 강화(업그레이드), 민첩(Dexterity).
## 규칙 (StS 표준)
| 상태 | 효과 | 지속 |
|------|------|------|
| 힘(Strength) | 공격 피해 +N | 전투 동안 영구 |
| 약화(Weak) | 주는 공격 피해 25% 감소 (floor) | N턴, 자기 턴 종료 시 1 감소 |
| 취약(Vulnerable) | 받는 공격 피해 50% 증가 (floor) | N턴, 자기 턴 종료 시 1 감소 |
피해 공식 (플레이어 공격): `floor( floor((base + 힘) × (약화 ? 0.75 : 1)) × (대상 취약 ? 1.5 : 1) )`
피해 공식 (적 공격): 동일 공식을 적 힘·적 약화·플레이어 취약으로 적용.
감소 타이밍:
- 플레이어 약화/취약 → `EndPlayerTurn`에서 1 감소
- 적 약화/취약 → 적 개별 행동(`EnemyActStep`) 종료 시 1 감소
## 상태 모델
- 플레이어: `PlayerStr` / `PlayerWeak` / `PlayerVuln` (number props), `PlayerPowers` (any)
- 몬스터: `m.str` / `m.weak` / `m.vuln` (BuildMonsters에서 0 초기화)
- 전투 시작(`StartCombat`) 시 전부 리셋
## 카드 데이터 스키마 확장 (`data/cards.json`)
| 필드 | 의미 |
|------|------|
| `kind: "Power"` | 파워 카드 — 사용 시 소멸, 전투 동안 지속 효과 |
| `weak: N` | 대상 적에게 약화 N 부여 |
| `vuln: N` | 대상 적에게 취약 N 부여 |
| `strength: N` | 자신에게 힘 +N |
| `powerEffect: "strengthPerTurn"`, `value: N` | 파워: 매 턴 시작 시 힘 +N |
`luaCardsTable`이 신규 필드를 직렬화하도록 확장.
## 예시 카드 4종 (메이플 스킬명 × StS 효과)
| id | 이름 | kind | 코스트 | 효과 | StS 원본 |
|----|------|------|--------|------|----------|
| ChargedBlow | 차지 블로우 | Attack | 2 | 피해 8, 취약 2 | Bash |
| Threaten | 위협 | Skill | 0 | 타겟 적에게 약화 2 | Intimidate 계열 |
| Enrage | 인레이지 | Skill | 1 | 힘 +2 | Inflame |
| Rage | 분노 | Power | 1 | 매 턴 시작 시 힘 +1 | Demon Form(경량) |
- 보상 풀은 `self.Cards` 전체 자동 편입이므로 추가 작업 없음. 시작 덱 변경 없음.
- 카드 이미지는 MSW 공식 리소스 RUID를 검색·선별해 사용 (계정 업로드 리소스는 로컬 워크스페이스에서 흰 박스 — 금지).
- 타겟팅: Attack은 기존 드래그 타겟, 디버프 Skill(위협)은 현재 `TargetIndex` 적에게 적용 (적 클릭으로 타겟 변경 가능).
## Power 카드 동작
- `PlayCard`에서 `kind == "Power"` 분기: `powerEffect` 등록(`PlayerPowers`에 push) 후 **버린 덱에 넣지 않고 소멸** (RunDeck에는 유지 — 다음 전투에서 다시 사용 가능)
- `StartPlayerTurn`: `PlayerPowers` 순회, `strengthPerTurn`이면 `PlayerStr += value`
- 카드 면 색: 기존 `ApplyCardFace`의 else 분기(초록)가 Power에 적용됨 — 명시적으로 `elseif c.kind == "Power"` 초록 지정
## 적 디버프 인텐트 (`data/enemies.json`)
인텐트 스키마 확장: `{ "kind": "Debuff", "effect": "weak"|"vuln", "value": N }`
| 적 | 추가 인텐트 |
|----|------------|
| mushmom (머쉬맘) | 포자 — 약화 2 |
| slime_elite (정예 슬라임) | 약화 1 |
| slime_boss (슬라임 킹) | 취약 2 |
| king_slime (킹 슬라임) | 취약 2 |
| modified_snail (변형된 달팽이) | 약화 1 |
`EnemyActStep`에서 `kind == "Debuff"` 처리: `PlayerWeak/PlayerVuln += value`.
## UI 변경 (`gen-slaydeck.mjs` UI 생성부)
1. **적 방어도 배지**: 각 `MonsterSlot{i}``BlockBadge`(파란 사각 44×40, HP바 좌측 x=-HP_BAR_W/2-32, y=-14) + `BlockBadge/Value` 텍스트. `RenderCombat`에서 `m.block > 0`일 때만 표시 — 플레이어 배지와 동일 패턴.
2. **적 버프 라인**: `MonsterSlot{i}/Buffs` 텍스트 (Intent 아래 y=-58, fontSize 15, 보라). 예: `힘+2 약화1 취약2`. 없으면 빈 문자열.
3. **플레이어 버프 라인**: `PlayerPanel/Buffs` 텍스트 (y=-44, fontSize 14). 파워 활성 시 `분노` 포함. 예: `힘+3 취약1 · 분노`.
4. **인텐트 표시 확장**: `Debuff` 인텐트 → `약화 2 부여` / `취약 2 부여`, 보라색. Attack 인텐트 숫자는 힘·약화·플레이어 취약 반영한 **최종 예상치** 표시 (StS 동일).
## 밸런스 시뮬 동기화 (`tools/balance/sim-balance.mjs`)
- 카드: `strength`/`weak`/`vuln`/Power 처리 재현 (chooseAction은 Attack 우선 휴리스틱 유지, Power/버프 스킬은 에너지 남을 때 사용하는 단순 규칙 추가)
- 적: `Debuff` 인텐트 재현 (플레이어 weak/vuln)
- 피해 공식 양방향 동일 적용, 감소 타이밍 동일
- 기존 테스트(`sim-balance.test.mjs`) 통과 + 신규 케이스(약화/취약/힘 계산 단위 테스트) 추가
## 검증
1. `node tools/deck/gen-slaydeck.mjs` 성공 (산출물 재생성: SlayDeckController.codeblock·DefaultGroup.ui·common.gamelogic)
2. `node --test tools/balance/sim-balance.test.mjs` 통과
3. `node tools/balance/sim-balance.mjs` 실행 — 승률이 0%/100% 극단으로 붕괴하지 않는지 확인
## 결정 사항
- 민첩(Dexterity)은 도입하지 않음 (방어 카드 수가 적어 효용 낮음 — YAGNI)
- 기존 카드(슬래시 블러스트 등) 수치 변경 없음 — 신규 카드로만 확장
- Power는 1종으로 시작, 물약/유물(P7)과의 연계는 P7에서