docs(card-frames): P13 설계·계획 — 커스텀 카드 프레임(직업×등급)·보상 가중
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
81
docs/superpowers/specs/2026-06-12-card-frames-design.md
Normal file
81
docs/superpowers/specs/2026-06-12-card-frames-design.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# P13 — 커스텀 카드 프레임 설계
|
||||
|
||||
날짜: 2026-06-12 (사용자 승인 완료)
|
||||
브랜치: `feature/p13-card-frames`
|
||||
|
||||
## 범위
|
||||
|
||||
사용자 제작 카드 프레임 이미지(직업 3종 × 등급 3종)를 인게임 카드 UI 전체(손패·보상·상점·덱 조회)에 적용한다. 카드에 등급(rarity)을 도입하고 전투 보상 추첨 확률에 반영한다.
|
||||
|
||||
## 리소스 (임포트 완료 — RUID 수확됨)
|
||||
|
||||
원본: `C:\Users\jaeoh\Desktop\workspace\source\images\maple\card\*.png` (263×366, 카드 비율 180×250과 동일한 0.72)
|
||||
메이커 로컬 임포트 → `RootDesk/MyDesk/<name>.sprite` 디스크립터 9종 (커밋 대상).
|
||||
|
||||
| 프레임 | normal | unique | legend |
|
||||
|---|---|---|---|
|
||||
| warior | `4bb57ef88ef449fdaf958f6cf37fe44b` | `4f71c124c8bc4e13b5e9fad392995f68` | `6d741a60c60743cb98ee740a1e2dbfed` |
|
||||
| mage | `d788d09f6f50467ebc67f01dec45f9e2` | `f5def2e8022b4e59a17d3c16414034fe` | `cff71f2e472041ce80c6fbd296f42e2d` |
|
||||
| bandit | `9487b06867bc46269ed1d855420f457f` | `b3081fb2fb1445fa90b12b01481a78ef` | `c357d2daf31a489d95b8fa47e50dd879` |
|
||||
|
||||
bandit은 RUID 등록만 하고 보류 (도적 클래스 추가 시 사용).
|
||||
|
||||
프레임 슬롯 구조: 좌상단 육각 코스트 · 상단 이름 배너 · 중앙 아트 영역 · 하단 설명 박스.
|
||||
|
||||
## 데이터
|
||||
|
||||
### `data/cardframes.json` (신설)
|
||||
|
||||
```json
|
||||
{
|
||||
"frames": {
|
||||
"warrior": { "normal": "4bb57ef88ef449fdaf958f6cf37fe44b", "unique": "4f71c124c8bc4e13b5e9fad392995f68", "legend": "6d741a60c60743cb98ee740a1e2dbfed" },
|
||||
"magician": { "normal": "d788d09f6f50467ebc67f01dec45f9e2", "unique": "f5def2e8022b4e59a17d3c16414034fe", "legend": "cff71f2e472041ce80c6fbd296f42e2d" },
|
||||
"bandit": { "normal": "9487b06867bc46269ed1d855420f457f", "unique": "b3081fb2fb1445fa90b12b01481a78ef", "legend": "c357d2daf31a489d95b8fa47e50dd879" }
|
||||
},
|
||||
"classToFrame": {
|
||||
"warrior": "warrior", "fighter": "warrior", "page": "warrior", "spearman": "warrior",
|
||||
"magician": "magician", "firepoison": "magician", "icelightning": "magician", "cleric": "magician"
|
||||
},
|
||||
"rewardWeights": { "normal": 70, "unique": 25, "legend": 5 }
|
||||
}
|
||||
```
|
||||
|
||||
### `data/cards.json` — 전 카드에 `rarity` 추가
|
||||
|
||||
| 등급 | 카드 (32종) |
|
||||
|---|---|
|
||||
| normal (10) | Strike, Defend, Bash, WarLeap, Threaten, EnergyBolt, MagicGuard, MagicClaw, Teleport, Slow |
|
||||
| unique (17) | Brandish, ChargedBlow, Enrage, ComboAttack, RisingAttack, ThunderCharge, BlizzardCharge, PowerGuard, Pierce, IronWall, FireArrow, PoisonBreath, ColdBeam, ChillingStep, Heal, Bless, HolyArrow |
|
||||
| legend (5) | Rage, Berserk, HyperBody, ElementAmp, ThunderBolt |
|
||||
|
||||
기준: 시작 덱·기본기 = normal / 강화·2차 전직 주력기 = unique / 파워 카드·전체 공격 = legend.
|
||||
|
||||
생성기 검증: `rarity` 누락 또는 normal|unique|legend 외 값이면 throw. 카드 class가 `classToFrame`에 없으면 throw.
|
||||
|
||||
## 렌더링 (생성기 — A안: 카드 배경 교체)
|
||||
|
||||
- 카드 루트 스프라이트: 단색 틴트(kind별) → 프레임 `ImageRUID`(Type 0, 흰색). NamePlate/CostPlate 단색판 제거 — RewardHud 등 생성 섹션은 생성 중단으로 충분, **CardHand는 .ui에 잔존하므로 upsert 시 경로 매칭으로 명시 제거**.
|
||||
- `ApplyCardFace`(Lua): kind 틴트 분기 제거 → `self.CardFrames[self.ClassToFrame[c.class]][c.rarity]` 적용. `CardFrames`/`ClassToFrame`는 OnBeginPlay에서 Lua 테이블 주입 + `prop('any', …)` 선언(LIA 1114 예방).
|
||||
- 자식 레이아웃 공용 헬퍼 `cardFaceLayout(W)` 신설 — 중복 5곳(손패 523·조회 787·전체덱 928·보상 1443·상점 1660 부근) 일괄 적용. 180×250 기준값(스케일 s=W/180):
|
||||
- Cost: pos(-68, 103)·size 44·font 26 (현 위치와 거의 일치)
|
||||
- Name: pos(4, 97)·size 150×26·font 18 — 상단 배너로 이동
|
||||
- Art: pos(0, 16)·size 110 — 중앙 아트 영역 확대
|
||||
- Desc: pos(0, -85)·size 152×64·font 16 — 하단 박스
|
||||
- 초깃값이며 메이커 스크린샷으로 미세 튜닝.
|
||||
- 정적 프리뷰(Card1~5)도 동일 프레임 적용.
|
||||
|
||||
## 보상 가중 추첨
|
||||
|
||||
`OfferReward`(Lua): 풀을 rarity 버킷으로 분류 후 1~100 롤 — ≤70 normal / ≤95 unique / >95 legend. 해당 버킷이 비면 전체 풀 폴백. 상점·전투 계산은 변경 없음 (sim-balance 전투 미러 무관).
|
||||
|
||||
JS 미러: `tools/balance/sim-balance.mjs`에 `rarityForRoll(roll)` export + 경계 테스트(70/71/95/96).
|
||||
|
||||
## 검증
|
||||
|
||||
재생성 → `grep -c` 카운트(CardFrames·rarity) → 기존 테스트 40건 + 신규 통과 → 메이커 refresh·빌드 0에러 → 플레이 스크린샷(손패 프레임·등급 색 구분·보상·덱 조회) → 텍스트 위치 튜닝.
|
||||
|
||||
## 주의 (이번 세션 실측)
|
||||
|
||||
- maker_save 시 메이커가 산출물을 재직렬화(0→0.0 등)하고 `Mislocated/`로 엔티티를 옮길 수 있음 → 임포트 후 `.sprite`만 남기고 산출물은 `git restore`로 복원했음. 재발 시 동일 절차.
|
||||
- sprite RUID는 map01.map에 등록되지 않고 `.sprite` 디스크립터 자체가 등록 메커니즘.
|
||||
Reference in New Issue
Block a user