BurningTimesAi/프로젝트/EerieVillage/개발/spec/BT12-MVP-A_설계_v1.md

780 lines
31 KiB
Markdown
Raw Normal View History

docs(BT12-MVP-A Phase 1): 경험치·레벨업·UI 설계 v1 + dev-auditor 감사 자성 + feedback 2종 신설 PD 직접 지시 2026-05-08 — 2건: 1. 적 처치 시 EXP 획득 + 레벨업마다 스킬 카드 3개 선택 기능 2. 레벨업 시 스킬 카드 선택 UI (스킬 효과 추후·UI만) PD 결정 (2026-05-08·"위 계획대로 진행"): (β) 채택 — BT12-Dev 보류 일부 해제·BT12-MVP-A 분리 항목 진행 dev-auditor 감사 자성 (Critical 2·Major 5): - Critical 1 Agent 라우팅 오류 — 본 PM이 dev-auditor에 개발팀장 직무 위임 (C23 위반) - Critical 2 BT12-Dev 보류 외연 무단 해석 (PD 명시 (β) 채택 후 정합) - Major 3 C49 Phase 1 주체 위반 / Major 4 PlayerStats 충돌 검토 누락 / Major 5 C50 표현 모호 정상 개발팀장 호출 시도 실패: - subagent_type=개발팀장 → "Agent type not found" - 시스템 카탈로그 한글 agent (개발팀장·기획팀장·클라이언트팀장·서버팀장) 미등재 발견 - PM 직접 처리 절충 (Opus·임시 개발팀장 역할 위임·C23 외연 자성) Phase 1 설계 산출: - 프로젝트/EerieVillage/개발/spec/BT12-MVP-A_설계_v1.md (신규·~600 라인) - §1 BT12-Dev v1 충돌·중복 매트릭스 (PlayerStats 분리·PlayerProgression 신규) - §2 신규 컴포넌트 7종 - §3~§5 통합 hook·이벤트 흐름·UI Prefab (PD 예시 정합) - §7 Phase 2 분량 옵션 (PM 권고 b 분할 ~150K) - §10 본 설계 자성 헌법급 feedback 2종 신설: - feedback_pm_auditor_role_conflation (감사관·팀장 분리·C23·C43·C48·C49) - feedback_korean_agent_catalog_unregistered (project tier·시스템 정정 의무) PD 지시 로그: - BT12-MVP-A 분리 항목 신규 등록 (활성·진행중) - BT12-Dev 본격 영역 = 보류 유지 (기획서 v0.3 확정 대기) 매니페스트: 2026-05-08_BT12MVPA_Phase1 archived Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 08:45:27 +00:00
---
type: 설계_문서
scope: BT12-MVP-A — 경험치·레벨업·스킬_카드_선택_UI
author: 총괄PM (임시 개발팀장 역할 위임 — 시스템 카탈로그 한글 agent 미등재 절충)
date: 2026-05-08
version: v1.0 (Phase 1 설계)
project: EerieVillage (기묘한 고을 : 조선퇴마뎐 / EerieVillage: Joseon Exorcist)
phase: BT12-MVP-A Phase 1 — 설계
data_source: 프로젝트/EerieVillage/개발/spec/스킬_시스템_설계_v1.md (BT12-Dev v1 1074 라인) · 프로젝트/EerieVillage/기획/balance/02_레벨업_곡선.md v0.2 · 프로젝트/EerieVillage/기획/content/02_스킬_효과_컨셉.md v0.2 (BT11-Plan 60종) · PD 첨부 예시 이미지 (2026-05-08 "기술 선택" UI)
status: Phase 1 설계 완료 — Phase 2 구현 분량 사전 PD 승인 대기 · Phase 3 검증 대기
# 본 문서 임시 위임 자성 (C23 외연 명시)
본 설계는 정상 개발팀장 agent 시스템 카탈로그 미등재 영역 한계 절충. 총괄PM (Opus·본 PM) 임시 개발팀장 역할 위임. 차기 영역 Anthropic Claude Code 카탈로그 한글 agent 등재 정정 의무 (`feedback_korean_agent_catalog_unregistered.md` 신설). 본 산출물 정합 검증 = Phase 3 시점 dev-auditor 감사 의무.
---
# BT12-MVP-A 설계 v1 — 경험치·레벨업·스킬 카드 선택 UI
## §0. 본 작업 범위 명확화
### 0-1. PD 직접 지시 (2026-05-08)
1. 적 처치 시 경험치 획득 + 레벨업마다 스킬 카드 3개 선택 기능
2. 레벨업 시 스킬 카드 선택 UI (스킬 효과 추후 구현·UI만)
### 0-2. PD 결정 채택 (2026-05-08·"위 계획대로 진행")
본 PM 권고 (β) 채택:
- BT12-Dev 보류 일부 해제 — Phase 1-A (경험치·레벨업·UI) 선행
- BT12-Dev v1 1074 라인 자산 활용 + 신규 영역 분리
- 60종 카드 효과 적용은 BT12-Dev 후속 영역 (기획서 v0.3 확정 대기)
### 0-3. 본 작업 = BT12-MVP-A (BT12-Dev 분리 항목)
PD 지시 로그 영역 BT12-Dev 활성 항목 = 보류 유지. 본 작업 = **신규 분리 항목 BT12-MVP-A** 등록.
---
## §1. BT12-Dev v1 충돌·중복 매트릭스 (dev-auditor Major 4 정정)
| BT12-Dev v1 (1074 라인) | 본 작업 영역 | 통합·분리 결정 | 사유 |
|------|-----|-----|------|
| `PlayerStats` POCO (DamageMultiplier·CooldownMultiplier·XPMultiplier 등 패시브 보정) | Level·EXP·EXP-to-next 진행도 | **분리**`PlayerProgression` 신규 클래스 | Single Responsibility (보정 vs 진행도) · BT12-Dev v1 영역 변경 X · 차기 본격 착수 시점 충돌 X |
| `ActiveSkillData·PassiveSkillData·AwakeningSkillData` ScriptableObject 3종 (효과 정의) | placeholder 카드 표시 영역 | **신규 분리**`SkillCardPlaceholder` ScriptableObject | 효과 영역 정의 X (PD 명시 "기능 추후") · placeholder는 표시 영역만 (이름·설명·등급·아이콘) · 차기 본격 영역 = `SkillCardPlaceholder` 영역 deprecate + ScriptableObject 3종 활용 |
| `PlayerSkillInventory` (60종 카드 보유·슬롯 6+6+6) | 선택 카드 보유 영역 | **사용 X** | 본 작업 영역 = 카드 효과 적용 X = Inventory 영역 미적용. 차기 본격 영역에 통합 |
| `SkillRuntimeFactory` (CSV → ScriptableObject → Runtime) | placeholder 카드 풀 | **신규 분리**`SkillCardPlaceholderPool` | CSV 변환 영역 X · 5~8장 placeholder ScriptableObject 직접 List<>·인스펙터 영역 |
| `SkillCsvImporter` 에디터 툴 | 미사용 | **사용 X** | placeholder 영역 직접 작성 |
| `Schedule<T>` 이벤트 시스템 (Simulation) | 레벨업 발화 | **활용**`Schedule<PlayerLeveledUp>()` 신규 이벤트 | 기존 패턴 정합 |
### §1-1. 결론
본 작업 영역 = **BT12-Dev v1 영역 변경 X**. 신규 6 클래스 분리 + 기존 `Simulation.Schedule<T>` 이벤트 시스템 + `Health` API 활용. BT12-Dev v1 영역은 차기 본격 착수 시점 그대로 활용 가능.
---
## §2. 신규 컴포넌트 설계
### 2-1. `PlayerProgression` (POCO + MonoBehaviour)
```csharp
namespace EerieVillage.Progression
{
/// <summary>
/// 플레이어 레벨업 진행도. BT12-Dev v1 PlayerStats(패시브 보정)와 직무 분리.
/// XP는 적 처치 시 누적. 임계점 도달 시 OnLevelUp event 발화.
/// </summary>
public class PlayerProgression : MonoBehaviour
{
public int Level { get; private set; } = 1;
public int CurrentXP { get; private set; } = 0;
public int XPToNextLevel { get; private set; } = 10;
/// <summary>레벨업 발화 — LevelUpManager 구독 hook</summary>
public event System.Action<int> OnLevelUp; // int = new Level
/// <summary>적 처치 시 호출 — XP 획득</summary>
public void GainXP(int amount)
{
if (amount <= 0) return;
CurrentXP += amount;
while (CurrentXP >= XPToNextLevel)
{
CurrentXP -= XPToNextLevel;
Level++;
XPToNextLevel = ComputeXPToNextLevel(Level);
OnLevelUp?.Invoke(Level);
}
}
/// <summary>EXP 곡선. balance/02 v0.2 §3 영역 정합 — placeholder 영역.</summary>
static int ComputeXPToNextLevel(int level)
{
// balance/02 v0.2 §3 — 80 + Level × 20 영역 (placeholder)
return 80 + level * 20;
}
}
}
```
**위치**: `Assets/Scripts/Progression/PlayerProgression.cs` (신규 디렉토리)
**부착**: `Player.prefab` (자동 부착 — `PlayerController.Awake` 영역에 GetOrAdd)
### 2-2. `ExperienceSystem` (정적 게이트웨이)
```csharp
namespace EerieVillage.Progression
{
/// <summary>
/// EXP 발급 정적 영역. EnemyDeath 영역 단일 호출 통로.
/// 차기 영역 P19 XPMultiplier 영역 적용 hook.
/// </summary>
public static class ExperienceSystem
{
public static void OnEnemyKilled(EnemyController enemy, PlayerController player)
{
if (player == null) return;
var prog = player.GetComponent<PlayerProgression>();
if (prog == null) return;
int xp = ComputeXPReward(enemy);
prog.GainXP(xp);
}
/// <summary>placeholder — 적 종류·등급별 XP 영역 차기 BT12-Dev 영역</summary>
static int ComputeXPReward(EnemyController enemy)
{
return 5; // placeholder. 차기 = enemy.xpReward 또는 EnemyData ScriptableObject
}
}
}
```
**위치**: `Assets/Scripts/Progression/ExperienceSystem.cs`
### 2-3. `LevelUpManager` (MonoBehaviour 싱글톤)
```csharp
namespace EerieVillage.Progression
{
/// <summary>
/// 레벨업 발화 시 일시정지 + UI 호출 + 카드 선택 결과 수령.
/// PlayerProgression.OnLevelUp 구독.
/// </summary>
public class LevelUpManager : MonoBehaviour
{
public static LevelUpManager Instance { get; private set; }
[SerializeField] SkillSelectionUI _ui; // Inspector 부착 또는 Resources.Load
[SerializeField] SkillCardPlaceholderPool _pool;
PlayerController _player;
bool _isLevelUpActive = false;
void Awake()
{
if (Instance != null) { Destroy(gameObject); return; }
Instance = this;
DontDestroyOnLoad(gameObject);
}
void Start()
{
_player = Object.FindFirstObjectByType<PlayerController>();
if (_player == null) return;
var prog = _player.GetComponent<PlayerProgression>();
if (prog != null) prog.OnLevelUp += OnLevelUp;
}
void OnLevelUp(int newLevel)
{
if (_isLevelUpActive) return; // 동시 레벨업 방지
_isLevelUpActive = true;
// 일시정지 + 입력 차단
Time.timeScale = 0f;
if (_player != null) _player.controlEnabled = false;
// 카드 3장 무작위 추출 + UI 표시
var cards = _pool.Draw3Random();
_ui.Show(cards, newLevel, OnCardConfirmed);
}
void OnCardConfirmed(SkillCardPlaceholder selected)
{
// 차기 BT12-Dev 영역 = PlayerSkillInventory.AddSkillByCardId(selected.id)
// 본 작업 영역 = UI 닫기만
_ui.Hide();
Time.timeScale = 1f;
if (_player != null) _player.controlEnabled = true;
_isLevelUpActive = false;
}
}
}
```
**위치**: `Assets/Scripts/Progression/LevelUpManager.cs`
**부착**: `Ingame.unity` Scene 영역 신규 GameObject `[LevelUpManager]`
### 2-4. `SkillCardPlaceholder` (ScriptableObject)
```csharp
namespace EerieVillage.Progression
{
[CreateAssetMenu(menuName = "EerieVillage/SkillCardPlaceholder")]
public class SkillCardPlaceholder : ScriptableObject
{
public string id; // 고유 ID (예: "A01_jineonbu")
public string displayName; // 한글 카드명 (예: "진언부")
[TextArea(2, 4)]
public string description; // 효과 설명 (3~4 라인·placeholder)
public Sprite icon; // 원형 아이콘
public CardRarity rarity; // 등급 (Common·Rare·Max)
public int currentLevel = 1; // PD 예시 영역 "레벨 N"
public int maxLevel = 5; // PD 예시 영역 "최대" 표시
}
public enum CardRarity { Common, Rare, Max }
}
```
**위치**: `Assets/Scripts/Progression/SkillCardPlaceholder.cs` + `Assets/Data/SkillPlaceholders/*.asset` (5~8장)
docs(BT12-MVP-A Phase 2-B asset 5 + 후속 정정): 설계서 §2-4 BT11 v0.2 정합 + PD Editor 가이드 + 대화로그 엔트리 10 EerieVillage 외부 레포 commit `755a51c` (asset 5 + meta 5 + folder meta 2 = 12 파일) 정합 + BurningTimes 후속 4 파일 산출물: - 설계서 v1 §2-4 + §7-1 정정 (P01·P12·AW01 한글명·id 정정·정정 이력 추가·기획팀 별도 안건 자진 고지) - BT12-MVP-A_Phase2B_PDEditor가이드.md (신규·B Prefab + C Scene 단계별·field 매핑·검증 영역·회귀 위험) - 대화로그 엔트리 10 (dev-team-lead 첫 정합 호출 + Sonnet 위임 + pm-auditor 검색 경로 오진 자성 + 통합 재감사 Pass) - 개발팀 PD 지시 로그 BT12-MVP-A 갱신 (Phase 2-B asset 5 산출물·PM 후속 대기 5종) C49 표준 - Phase 1 dev-team-lead Opus 첫 정합 + Phase 2 Sonnet 위임 + Phase 3 PM 검증 C42-7 + C44 - pm-auditor 검색 경로 오진 영역 본 PM 직접 재검증·실측 인용 정합 C35-9 매니페스트 등록 + pm-auditor 통합 재감사 Pass dev-team-lead 자진 고지 - 설계서 §2-4 BT11-Plan v0.2 정합 X 정정 적용 본 PM 자성 누적 3건: 1. dev-team-lead 호출 분량 추정 50~80K → 실제 116K (C50 정확도 ↑ 의무) 2. pm-auditor 의뢰문 외부 레포 경로 명시 부족 (정정 적용) 3. dev-team-lead Phase 1 자성 영역 본 PM BT11 v0.2 grep 검증 부족 pm-auditor 자체 자성 (Critical 자체 보고): - 직전 호출 영역 검색 경로 오진 (C5·C44·C42-D 위반) - 헌법급 feedback `feedback_pm_auditor_search_scope_external_repo` 신설 의무 (별도 commit) 후속 영역: - B (Prefab) + C (Scene) PD Editor 직접 작업 (가이드 정합) - Phase 3 dev-team-lead 통합 검증 - 기획팀 별도 안건 (`01_카드_풀.md` line 114 P12 = "도약강화" 정정)
2026-05-08 10:18:10 +00:00
**Placeholder 카드 5장 (BT11-Plan v0.2 `02_스킬_효과_컨셉.md` 정합·2026-05-08 정정)**:
docs(BT12-MVP-A Phase 1): 경험치·레벨업·UI 설계 v1 + dev-auditor 감사 자성 + feedback 2종 신설 PD 직접 지시 2026-05-08 — 2건: 1. 적 처치 시 EXP 획득 + 레벨업마다 스킬 카드 3개 선택 기능 2. 레벨업 시 스킬 카드 선택 UI (스킬 효과 추후·UI만) PD 결정 (2026-05-08·"위 계획대로 진행"): (β) 채택 — BT12-Dev 보류 일부 해제·BT12-MVP-A 분리 항목 진행 dev-auditor 감사 자성 (Critical 2·Major 5): - Critical 1 Agent 라우팅 오류 — 본 PM이 dev-auditor에 개발팀장 직무 위임 (C23 위반) - Critical 2 BT12-Dev 보류 외연 무단 해석 (PD 명시 (β) 채택 후 정합) - Major 3 C49 Phase 1 주체 위반 / Major 4 PlayerStats 충돌 검토 누락 / Major 5 C50 표현 모호 정상 개발팀장 호출 시도 실패: - subagent_type=개발팀장 → "Agent type not found" - 시스템 카탈로그 한글 agent (개발팀장·기획팀장·클라이언트팀장·서버팀장) 미등재 발견 - PM 직접 처리 절충 (Opus·임시 개발팀장 역할 위임·C23 외연 자성) Phase 1 설계 산출: - 프로젝트/EerieVillage/개발/spec/BT12-MVP-A_설계_v1.md (신규·~600 라인) - §1 BT12-Dev v1 충돌·중복 매트릭스 (PlayerStats 분리·PlayerProgression 신규) - §2 신규 컴포넌트 7종 - §3~§5 통합 hook·이벤트 흐름·UI Prefab (PD 예시 정합) - §7 Phase 2 분량 옵션 (PM 권고 b 분할 ~150K) - §10 본 설계 자성 헌법급 feedback 2종 신설: - feedback_pm_auditor_role_conflation (감사관·팀장 분리·C23·C43·C48·C49) - feedback_korean_agent_catalog_unregistered (project tier·시스템 정정 의무) PD 지시 로그: - BT12-MVP-A 분리 항목 신규 등록 (활성·진행중) - BT12-Dev 본격 영역 = 보류 유지 (기획서 v0.3 확정 대기) 매니페스트: 2026-05-08_BT12MVPA_Phase1 archived Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 08:45:27 +00:00
| ID | 한글명 | 등급 | 설명 (placeholder) |
|----|------|------|------|
docs(BT12-MVP-A Phase 2-B asset 5 + 후속 정정): 설계서 §2-4 BT11 v0.2 정합 + PD Editor 가이드 + 대화로그 엔트리 10 EerieVillage 외부 레포 commit `755a51c` (asset 5 + meta 5 + folder meta 2 = 12 파일) 정합 + BurningTimes 후속 4 파일 산출물: - 설계서 v1 §2-4 + §7-1 정정 (P01·P12·AW01 한글명·id 정정·정정 이력 추가·기획팀 별도 안건 자진 고지) - BT12-MVP-A_Phase2B_PDEditor가이드.md (신규·B Prefab + C Scene 단계별·field 매핑·검증 영역·회귀 위험) - 대화로그 엔트리 10 (dev-team-lead 첫 정합 호출 + Sonnet 위임 + pm-auditor 검색 경로 오진 자성 + 통합 재감사 Pass) - 개발팀 PD 지시 로그 BT12-MVP-A 갱신 (Phase 2-B asset 5 산출물·PM 후속 대기 5종) C49 표준 - Phase 1 dev-team-lead Opus 첫 정합 + Phase 2 Sonnet 위임 + Phase 3 PM 검증 C42-7 + C44 - pm-auditor 검색 경로 오진 영역 본 PM 직접 재검증·실측 인용 정합 C35-9 매니페스트 등록 + pm-auditor 통합 재감사 Pass dev-team-lead 자진 고지 - 설계서 §2-4 BT11-Plan v0.2 정합 X 정정 적용 본 PM 자성 누적 3건: 1. dev-team-lead 호출 분량 추정 50~80K → 실제 116K (C50 정확도 ↑ 의무) 2. pm-auditor 의뢰문 외부 레포 경로 명시 부족 (정정 적용) 3. dev-team-lead Phase 1 자성 영역 본 PM BT11 v0.2 grep 검증 부족 pm-auditor 자체 자성 (Critical 자체 보고): - 직전 호출 영역 검색 경로 오진 (C5·C44·C42-D 위반) - 헌법급 feedback `feedback_pm_auditor_search_scope_external_repo` 신설 의무 (별도 commit) 후속 영역: - B (Prefab) + C (Scene) PD Editor 직접 작업 (가이드 정합) - Phase 3 dev-team-lead 통합 검증 - 기획팀 별도 안건 (`01_카드_풀.md` line 114 P12 = "도약강화" 정정)
2026-05-08 10:18:10 +00:00
| A01_jineonbu | 진언부(眞言符) | Common | 전방 직선 부적 투척. 단일 적 타격. 가장 기본 패턴. |
| A05_hagikjin | 학익진(鶴翼陣) | Common | 전방 부채꼴 자동 타격. 근접 다중 히트. 밀집 구간 특효. |
| P01_bonghwanggyeok | 봉황격(鳳凰擊) | Common | 모든 액티브 대미지 증가. 빌드 막론 범용 강화. |
| P12_saengmyeongkkot | 생명의 꽃(生命之花) | Rare | 최대 하트 수 +1. 즉시 회복. 각성 조건 핵심. |
| AW01_cheonbugyeongmun | 천부경문(天符經文) | Max | A01 진언부 각성. 화면 전체 부적 전개·전 적 일괄 강타. |
> **정정 이력 (2026-05-08·dev-team-lead Phase 1 자진 고지·BT12-MVP-A Phase 2-B asset 5 commit `755a51c` 정합)**:
> - P01: `P01_giryeon` 기 단련 → **`P01_bonghwanggyeok` 봉황격** (BT11 `02_스킬_효과_컨셉.md` line 357·v0.2 정식)
> - P12: `P12_bangho` 방호 → **`P12_saengmyeongkkot` 생명의 꽃** (구 P15 → 신 P12·`02_스킬_효과_컨셉.md` line 368·418 정정 정합)
> - AW01: `AW01_jineonjingyeong` 진언경 → **`AW01_cheonbugyeongmun` 천부경문** (`02_스킬_효과_컨셉.md` line 300·392)
> - 본 정정 = 본 설계서 §2-4 영역만. 기획팀 영역 `01_카드_풀.md` line 114 P12 = "도약강화" 잔존 (구 P12 폐기 미반영) → **기획팀 별도 정합 안건** (BT12-MVP-A 외 영역).
docs(BT12-MVP-A Phase 1): 경험치·레벨업·UI 설계 v1 + dev-auditor 감사 자성 + feedback 2종 신설 PD 직접 지시 2026-05-08 — 2건: 1. 적 처치 시 EXP 획득 + 레벨업마다 스킬 카드 3개 선택 기능 2. 레벨업 시 스킬 카드 선택 UI (스킬 효과 추후·UI만) PD 결정 (2026-05-08·"위 계획대로 진행"): (β) 채택 — BT12-Dev 보류 일부 해제·BT12-MVP-A 분리 항목 진행 dev-auditor 감사 자성 (Critical 2·Major 5): - Critical 1 Agent 라우팅 오류 — 본 PM이 dev-auditor에 개발팀장 직무 위임 (C23 위반) - Critical 2 BT12-Dev 보류 외연 무단 해석 (PD 명시 (β) 채택 후 정합) - Major 3 C49 Phase 1 주체 위반 / Major 4 PlayerStats 충돌 검토 누락 / Major 5 C50 표현 모호 정상 개발팀장 호출 시도 실패: - subagent_type=개발팀장 → "Agent type not found" - 시스템 카탈로그 한글 agent (개발팀장·기획팀장·클라이언트팀장·서버팀장) 미등재 발견 - PM 직접 처리 절충 (Opus·임시 개발팀장 역할 위임·C23 외연 자성) Phase 1 설계 산출: - 프로젝트/EerieVillage/개발/spec/BT12-MVP-A_설계_v1.md (신규·~600 라인) - §1 BT12-Dev v1 충돌·중복 매트릭스 (PlayerStats 분리·PlayerProgression 신규) - §2 신규 컴포넌트 7종 - §3~§5 통합 hook·이벤트 흐름·UI Prefab (PD 예시 정합) - §7 Phase 2 분량 옵션 (PM 권고 b 분할 ~150K) - §10 본 설계 자성 헌법급 feedback 2종 신설: - feedback_pm_auditor_role_conflation (감사관·팀장 분리·C23·C43·C48·C49) - feedback_korean_agent_catalog_unregistered (project tier·시스템 정정 의무) PD 지시 로그: - BT12-MVP-A 분리 항목 신규 등록 (활성·진행중) - BT12-Dev 본격 영역 = 보류 유지 (기획서 v0.3 확정 대기) 매니페스트: 2026-05-08_BT12MVPA_Phase1 archived Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 08:45:27 +00:00
### 2-5. `SkillCardPlaceholderPool` (MonoBehaviour)
```csharp
namespace EerieVillage.Progression
{
public class SkillCardPlaceholderPool : MonoBehaviour
{
[SerializeField] List<SkillCardPlaceholder> _allCards;
public List<SkillCardPlaceholder> Draw3Random()
{
// 5~8장에서 무작위 3장 (중복 X)
var copy = new List<SkillCardPlaceholder>(_allCards);
var result = new List<SkillCardPlaceholder>();
for (int i = 0; i < 3 && copy.Count > 0; i++)
{
int idx = Random.Range(0, copy.Count);
result.Add(copy[idx]);
copy.RemoveAt(idx);
}
return result;
}
}
}
```
**위치**: `Assets/Scripts/Progression/SkillCardPlaceholderPool.cs`
**부착**: `[LevelUpManager]` GameObject (자식 또는 Inspector field)
### 2-6. `SkillSelectionUI` (MonoBehaviour)
```csharp
namespace EerieVillage.UI
{
using EerieVillage.Progression;
public class SkillSelectionUI : MonoBehaviour
{
[Header("Root Canvas")]
[SerializeField] GameObject _rootPanel; // 일시정지 시 활성
[Header("Card Slots (3개 가로 배치)")]
[SerializeField] SkillCardSlot _slot1;
[SerializeField] SkillCardSlot _slot2;
[SerializeField] SkillCardSlot _slot3;
[Header("Header / Footer")]
[SerializeField] TMP_Text _titleText; // "기술 선택"
[SerializeField] TMP_Text _levelText; // "남은 포인트: 1"
[SerializeField] Button _confirmButton; // "확인"
[SerializeField] Button _closeButton; // X 버튼 (취소)
SkillCardPlaceholder _selected;
System.Action<SkillCardPlaceholder> _onConfirm;
public void Show(List<SkillCardPlaceholder> cards, int level, System.Action<SkillCardPlaceholder> onConfirm)
{
_onConfirm = onConfirm;
_rootPanel.SetActive(true);
_selected = null;
_confirmButton.interactable = false;
_levelText.text = $"남은 포인트: 1";
_slot1.Bind(cards[0], () => OnCardSelected(cards[0]));
_slot2.Bind(cards[1], () => OnCardSelected(cards[1]));
_slot3.Bind(cards[2], () => OnCardSelected(cards[2]));
_confirmButton.onClick.RemoveAllListeners();
_confirmButton.onClick.AddListener(OnConfirm);
_closeButton.onClick.RemoveAllListeners();
_closeButton.onClick.AddListener(OnClose);
}
public void Hide() { _rootPanel.SetActive(false); }
void OnCardSelected(SkillCardPlaceholder card)
{
_selected = card;
_confirmButton.interactable = true;
_slot1.SetHighlight(card == _slot1.Card);
_slot2.SetHighlight(card == _slot2.Card);
_slot3.SetHighlight(card == _slot3.Card);
}
void OnConfirm()
{
if (_selected == null) return;
_onConfirm?.Invoke(_selected);
}
void OnClose()
{
// PD 영역 결정 — 취소 시 어떻게? 본 작업 영역 = 첫 카드 자동 선택 또는 강제 1장 선택
// placeholder = 첫 카드 자동 선택
_onConfirm?.Invoke(_slot1.Card);
}
}
}
```
### 2-7. `SkillCardSlot` (MonoBehaviour — 단일 카드 표시)
```csharp
namespace EerieVillage.UI
{
using EerieVillage.Progression;
public class SkillCardSlot : MonoBehaviour
{
[Header("PD 예시 영역 정합 (2026-05-08)")]
[SerializeField] Image _topBanner; // 상단 색상 배너 (등급별 색상)
[SerializeField] TMP_Text _nameText; // 카드 이름
[SerializeField] Image _icon; // 원형 아이콘
[SerializeField] Image _glowEffect; // 동심원 빛 효과
[SerializeField] TMP_Text _levelText; // "레벨 N" 또는 "최대"
[SerializeField] TMP_Text _descriptionText;
[SerializeField] Button _clickArea;
[SerializeField] GameObject _highlightFrame; // 선택 시 표시
[Header("등급별 색상 (PD 예시 영역)")]
[SerializeField] Color _commonColor = new Color(0.3f, 0.7f, 0.7f); // 청록
[SerializeField] Color _rareColor = new Color(0.9f, 0.7f, 0.3f); // 노랑
[SerializeField] Color _maxColor = new Color(0.9f, 0.3f, 0.3f); // 빨강
public SkillCardPlaceholder Card { get; private set; }
public void Bind(SkillCardPlaceholder card, System.Action onClick)
{
Card = card;
_nameText.text = card.displayName;
_icon.sprite = card.icon;
_descriptionText.text = card.description;
// PD 예시 영역 — 등급별 색상 + "레벨 N" / "최대"
switch (card.rarity)
{
case CardRarity.Common: _topBanner.color = _commonColor; break;
case CardRarity.Rare: _topBanner.color = _rareColor; break;
case CardRarity.Max: _topBanner.color = _maxColor; break;
}
if (card.currentLevel >= card.maxLevel)
{
_levelText.text = "최대";
_levelText.color = _maxColor;
}
else
{
_levelText.text = $"레벨 {card.currentLevel}";
_levelText.color = Color.white;
}
_clickArea.onClick.RemoveAllListeners();
_clickArea.onClick.AddListener(() => onClick?.Invoke());
SetHighlight(false);
}
public void SetHighlight(bool active) { _highlightFrame.SetActive(active); }
}
}
```
---
## §3. 기존 시스템 통합 hook
### 3-1. `EnemyDeath` 영역 경험치 발급
```csharp
// 기존 EnemyDeath.Resolve 영역 마지막에 추가
namespace Platformer.Gameplay
{
public class EnemyDeath : Simulation.Event<EnemyDeath>
{
public EnemyController enemy;
public override void Execute()
{
// ... 기존 영역 ...
// BT12-MVP-A 신규 — 경험치 발급
var player = UnityEngine.Object.FindFirstObjectByType<PlayerController>();
EerieVillage.Progression.ExperienceSystem.OnEnemyKilled(enemy, player);
}
}
}
```
### 3-2. `PlayerController.Awake` 영역 자동 부착
```csharp
// 기존 PlayerController.Awake 영역에 추가
if (GetComponent<EerieVillage.Progression.PlayerProgression>() == null)
gameObject.AddComponent<EerieVillage.Progression.PlayerProgression>();
```
### 3-3. `Time.timeScale` 일시정지 영역
`LevelUpManager.OnLevelUp` 영역 `Time.timeScale = 0f` + 카드 확인 시 `Time.timeScale = 1f` 복원. UI 자체 영역은 `Time.unscaledDeltaTime` 활용 (UI 인터랙션 timeScale 영향 X).
### 3-4. `PlayerController.controlEnabled` 영역 입력 차단
기존 `OnHealthDeath`/`OnHealthResurrect` 영역과 동일 패턴 — `_player.controlEnabled = false` (UI 표시 시) → `true` (UI 닫기 시).
---
## §4. 이벤트 흐름
```
[적 처치]
EnemyDeath.Execute()
ExperienceSystem.OnEnemyKilled(enemy, player)
PlayerProgression.GainXP(5)
[CurrentXP >= XPToNextLevel]
PlayerProgression.OnLevelUp(newLevel) 발화
LevelUpManager.OnLevelUp 구독자
Time.timeScale = 0f + player.controlEnabled = false
SkillCardPlaceholderPool.Draw3Random() → List<SkillCardPlaceholder> 3장
SkillSelectionUI.Show(cards, level, onConfirm)
[사용자 카드 클릭]
SkillCardSlot.OnClick → SkillSelectionUI.OnCardSelected
[사용자 "확인" 버튼 클릭]
SkillSelectionUI.OnConfirm → onConfirm callback
LevelUpManager.OnCardConfirmed(selected)
[선택 결과 영역 — 본 작업 = UI 닫기만 / 차기 = PlayerSkillInventory.AddSkillByCardId]
SkillSelectionUI.Hide() + Time.timeScale = 1f + player.controlEnabled = true
[게임 재개]
```
---
## §5. UI Prefab 구조 (PD 예시 정합)
```
Canvas (Screen Space - Overlay·Sort Order 100)
└ SkillSelectionPanel (RootPanel·이미지 어두운 반투명 검정 배경)
├ Header
│ ├ TitleText "기술 선택" (TMP)
│ └ CloseButton "X" (우측 상단)
├ CardArea (Horizontal Layout Group)
│ ├ SkillCardSlot1
│ │ ├ TopBanner (Image·등급 색상)
│ │ ├ NameText (TMP·한글)
│ │ ├ IconArea
│ │ │ ├ GlowEffect (Image·동심원 빛)
│ │ │ └ Icon (Image·원형 sprite)
│ │ ├ LevelText (TMP·"레벨 N"/"최대")
│ │ ├ DescriptionText (TMP·3~4 라인)
│ │ ├ ClickArea (Button·전체 카드 영역)
│ │ └ HighlightFrame (선택 시 활성)
│ ├ SkillCardSlot2 (동일 구조)
│ └ SkillCardSlot3 (동일 구조)
└ Footer
├ LevelText "남은 포인트: 1"
└ ConfirmButton "확인"
```
**Sprite/Image 자산 (placeholder)**:
- 카드 회색 배경: 단일 색상 패널 또는 9-slice 스프라이트
- 원형 아이콘 배경: 회색 원형 sprite
- 동심원 빛: 흰색 → 투명 그라데이션 sprite
- 등급 색상: 청록 (Common) · 노랑 (Rare) · 빨강 (Max)
- 카드 아이콘: placeholder 5장 단순 sprite (하트·검·방패·바람·달 등)
---
## §6. balance/02 v0.2 영역 정합 + JSON 테이블 관리 (PD 직접 지시 2026-05-08)
docs(BT12-MVP-A Phase 1): 경험치·레벨업·UI 설계 v1 + dev-auditor 감사 자성 + feedback 2종 신설 PD 직접 지시 2026-05-08 — 2건: 1. 적 처치 시 EXP 획득 + 레벨업마다 스킬 카드 3개 선택 기능 2. 레벨업 시 스킬 카드 선택 UI (스킬 효과 추후·UI만) PD 결정 (2026-05-08·"위 계획대로 진행"): (β) 채택 — BT12-Dev 보류 일부 해제·BT12-MVP-A 분리 항목 진행 dev-auditor 감사 자성 (Critical 2·Major 5): - Critical 1 Agent 라우팅 오류 — 본 PM이 dev-auditor에 개발팀장 직무 위임 (C23 위반) - Critical 2 BT12-Dev 보류 외연 무단 해석 (PD 명시 (β) 채택 후 정합) - Major 3 C49 Phase 1 주체 위반 / Major 4 PlayerStats 충돌 검토 누락 / Major 5 C50 표현 모호 정상 개발팀장 호출 시도 실패: - subagent_type=개발팀장 → "Agent type not found" - 시스템 카탈로그 한글 agent (개발팀장·기획팀장·클라이언트팀장·서버팀장) 미등재 발견 - PM 직접 처리 절충 (Opus·임시 개발팀장 역할 위임·C23 외연 자성) Phase 1 설계 산출: - 프로젝트/EerieVillage/개발/spec/BT12-MVP-A_설계_v1.md (신규·~600 라인) - §1 BT12-Dev v1 충돌·중복 매트릭스 (PlayerStats 분리·PlayerProgression 신규) - §2 신규 컴포넌트 7종 - §3~§5 통합 hook·이벤트 흐름·UI Prefab (PD 예시 정합) - §7 Phase 2 분량 옵션 (PM 권고 b 분할 ~150K) - §10 본 설계 자성 헌법급 feedback 2종 신설: - feedback_pm_auditor_role_conflation (감사관·팀장 분리·C23·C43·C48·C49) - feedback_korean_agent_catalog_unregistered (project tier·시스템 정정 의무) PD 지시 로그: - BT12-MVP-A 분리 항목 신규 등록 (활성·진행중) - BT12-Dev 본격 영역 = 보류 유지 (기획서 v0.3 확정 대기) 매니페스트: 2026-05-08_BT12MVPA_Phase1 archived Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 08:45:27 +00:00
### 6-1. PD 결정 — JSON 테이블 영역 관리 의무
docs(BT12-MVP-A Phase 1): 경험치·레벨업·UI 설계 v1 + dev-auditor 감사 자성 + feedback 2종 신설 PD 직접 지시 2026-05-08 — 2건: 1. 적 처치 시 EXP 획득 + 레벨업마다 스킬 카드 3개 선택 기능 2. 레벨업 시 스킬 카드 선택 UI (스킬 효과 추후·UI만) PD 결정 (2026-05-08·"위 계획대로 진행"): (β) 채택 — BT12-Dev 보류 일부 해제·BT12-MVP-A 분리 항목 진행 dev-auditor 감사 자성 (Critical 2·Major 5): - Critical 1 Agent 라우팅 오류 — 본 PM이 dev-auditor에 개발팀장 직무 위임 (C23 위반) - Critical 2 BT12-Dev 보류 외연 무단 해석 (PD 명시 (β) 채택 후 정합) - Major 3 C49 Phase 1 주체 위반 / Major 4 PlayerStats 충돌 검토 누락 / Major 5 C50 표현 모호 정상 개발팀장 호출 시도 실패: - subagent_type=개발팀장 → "Agent type not found" - 시스템 카탈로그 한글 agent (개발팀장·기획팀장·클라이언트팀장·서버팀장) 미등재 발견 - PM 직접 처리 절충 (Opus·임시 개발팀장 역할 위임·C23 외연 자성) Phase 1 설계 산출: - 프로젝트/EerieVillage/개발/spec/BT12-MVP-A_설계_v1.md (신규·~600 라인) - §1 BT12-Dev v1 충돌·중복 매트릭스 (PlayerStats 분리·PlayerProgression 신규) - §2 신규 컴포넌트 7종 - §3~§5 통합 hook·이벤트 흐름·UI Prefab (PD 예시 정합) - §7 Phase 2 분량 옵션 (PM 권고 b 분할 ~150K) - §10 본 설계 자성 헌법급 feedback 2종 신설: - feedback_pm_auditor_role_conflation (감사관·팀장 분리·C23·C43·C48·C49) - feedback_korean_agent_catalog_unregistered (project tier·시스템 정정 의무) PD 지시 로그: - BT12-MVP-A 분리 항목 신규 등록 (활성·진행중) - BT12-Dev 본격 영역 = 보류 유지 (기획서 v0.3 확정 대기) 매니페스트: 2026-05-08_BT12MVPA_Phase1 archived Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 08:45:27 +00:00
PD 직접 지시 (2026-05-08·"경험치는 json 형태로 테이블로 관리할 수 있도록 설계"):
- **코드 산식 영역 폐기** — `ComputeXPToNextLevel(level) = 80 + level × 20` 영역 X
- **JSON 파일 영역 테이블 관리** 채택 — balance-designer 영역 직접 편집 가능 + 코드 영역 변경 X·JSON 영역만 정정
docs(BT12-MVP-A Phase 1): 경험치·레벨업·UI 설계 v1 + dev-auditor 감사 자성 + feedback 2종 신설 PD 직접 지시 2026-05-08 — 2건: 1. 적 처치 시 EXP 획득 + 레벨업마다 스킬 카드 3개 선택 기능 2. 레벨업 시 스킬 카드 선택 UI (스킬 효과 추후·UI만) PD 결정 (2026-05-08·"위 계획대로 진행"): (β) 채택 — BT12-Dev 보류 일부 해제·BT12-MVP-A 분리 항목 진행 dev-auditor 감사 자성 (Critical 2·Major 5): - Critical 1 Agent 라우팅 오류 — 본 PM이 dev-auditor에 개발팀장 직무 위임 (C23 위반) - Critical 2 BT12-Dev 보류 외연 무단 해석 (PD 명시 (β) 채택 후 정합) - Major 3 C49 Phase 1 주체 위반 / Major 4 PlayerStats 충돌 검토 누락 / Major 5 C50 표현 모호 정상 개발팀장 호출 시도 실패: - subagent_type=개발팀장 → "Agent type not found" - 시스템 카탈로그 한글 agent (개발팀장·기획팀장·클라이언트팀장·서버팀장) 미등재 발견 - PM 직접 처리 절충 (Opus·임시 개발팀장 역할 위임·C23 외연 자성) Phase 1 설계 산출: - 프로젝트/EerieVillage/개발/spec/BT12-MVP-A_설계_v1.md (신규·~600 라인) - §1 BT12-Dev v1 충돌·중복 매트릭스 (PlayerStats 분리·PlayerProgression 신규) - §2 신규 컴포넌트 7종 - §3~§5 통합 hook·이벤트 흐름·UI Prefab (PD 예시 정합) - §7 Phase 2 분량 옵션 (PM 권고 b 분할 ~150K) - §10 본 설계 자성 헌법급 feedback 2종 신설: - feedback_pm_auditor_role_conflation (감사관·팀장 분리·C23·C43·C48·C49) - feedback_korean_agent_catalog_unregistered (project tier·시스템 정정 의무) PD 지시 로그: - BT12-MVP-A 분리 항목 신규 등록 (활성·진행중) - BT12-Dev 본격 영역 = 보류 유지 (기획서 v0.3 확정 대기) 매니페스트: 2026-05-08_BT12MVPA_Phase1 archived Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 08:45:27 +00:00
### 6-2. JSON 테이블 영역 SOT
**경로**: `Assets/Data/Progression/level_xp_table.json`
**형식**:
```json
{
"version": "0.1",
"description": "레벨별 다음 레벨 도달 EXP 영역 테이블. balance-designer SOT 영역.",
"fallback_formula": "level <= 0 시 100·table 미정의 시 last_level + 20",
"max_level_in_table": 30,
"table": [
{ "level": 1, "xp_to_next": 100 },
{ "level": 2, "xp_to_next": 120 },
{ "level": 3, "xp_to_next": 140 },
{ "level": 4, "xp_to_next": 160 },
{ "level": 5, "xp_to_next": 180 },
{ "level": 6, "xp_to_next": 200 },
{ "level": 7, "xp_to_next": 220 },
{ "level": 8, "xp_to_next": 240 },
{ "level": 9, "xp_to_next": 260 },
{ "level": 10, "xp_to_next": 280 },
{ "level": 11, "xp_to_next": 320 },
{ "level": 12, "xp_to_next": 360 },
{ "level": 13, "xp_to_next": 400 },
{ "level": 14, "xp_to_next": 440 },
{ "level": 15, "xp_to_next": 480 },
{ "level": 16, "xp_to_next": 520 },
{ "level": 17, "xp_to_next": 560 },
{ "level": 18, "xp_to_next": 600 },
{ "level": 19, "xp_to_next": 640 },
{ "level": 20, "xp_to_next": 680 },
{ "level": 21, "xp_to_next": 760 },
{ "level": 22, "xp_to_next": 840 },
{ "level": 23, "xp_to_next": 920 },
{ "level": 24, "xp_to_next": 1000 },
{ "level": 25, "xp_to_next": 1080 },
{ "level": 26, "xp_to_next": 1160 },
{ "level": 27, "xp_to_next": 1240 },
{ "level": 28, "xp_to_next": 1320 },
{ "level": 29, "xp_to_next": 1400 },
{ "level": 30, "xp_to_next": 1480 }
]
}
```
**곡선 설계 (placeholder)**:
- Lv 1~10 = balance/02 v0.2 §3 영역 정합 (`80 + L × 20` 영역 base)
- Lv 11~20 = 곡선 가속 (×2 증가폭)
- Lv 21~30 = 곡선 가속 (×4 증가폭)
- balance-designer 영역 차기 정정 가능 (JSON 직접 편집)
### 6-3. JSON 로더 영역 — `LevelXPTableLoader`
```csharp
namespace EerieVillage.Progression
{
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// JSON 영역 레벨업 EXP 테이블 로더. Resources.Load + JsonUtility 활용.
/// 정적 캐시 영역 — Awake 시점 1회 로드.
/// </summary>
public static class LevelXPTableLoader
{
[System.Serializable]
public class LevelXPEntry
{
public int level;
public int xp_to_next;
}
[System.Serializable]
public class LevelXPTable
{
public string version;
public string description;
public string fallback_formula;
public int max_level_in_table;
public LevelXPEntry[] table;
}
static Dictionary<int, int> _cache;
static int _maxLevelInTable;
const int FALLBACK_BASE = 100;
const int FALLBACK_INCREMENT = 20;
public static void EnsureLoaded()
{
if (_cache != null) return;
var ta = Resources.Load<TextAsset>("Progression/level_xp_table");
if (ta == null)
{
Debug.LogWarning("[LevelXPTableLoader] Resources/Progression/level_xp_table.json 영역 부재 — fallback 영역 활성");
_cache = new Dictionary<int, int>();
_maxLevelInTable = 0;
return;
}
var data = JsonUtility.FromJson<LevelXPTable>(ta.text);
_cache = new Dictionary<int, int>();
_maxLevelInTable = data.max_level_in_table;
foreach (var entry in data.table)
{
_cache[entry.level] = entry.xp_to_next;
}
}
/// <summary>
/// 지정 level → 다음 레벨 도달 EXP. 테이블 영역 미정의 영역 = fallback 영역.
/// </summary>
public static int GetXPToNextLevel(int level)
{
EnsureLoaded();
if (level <= 0) return FALLBACK_BASE;
if (_cache.TryGetValue(level, out int xp)) return xp;
// 테이블 미정의 영역 — last 영역에서 선형 영역
if (_cache.TryGetValue(_maxLevelInTable, out int lastXp))
{
return lastXp + FALLBACK_INCREMENT * (level - _maxLevelInTable);
}
return FALLBACK_BASE + level * FALLBACK_INCREMENT;
}
}
}
```
**위치**: `Assets/Scripts/Progression/LevelXPTableLoader.cs` (신규)
### 6-4. `PlayerProgression` 영역 정정
§2-1 영역 `ComputeXPToNextLevel` 영역 폐기. JSON 로더 영역 위임:
```csharp
// §2-1 PlayerProgression 영역 정정
public class PlayerProgression : MonoBehaviour
{
public int Level { get; private set; } = 1;
public int CurrentXP { get; private set; } = 0;
public int XPToNextLevel { get; private set; } = 100;
public event System.Action<int> OnLevelUp;
void Awake()
{
// JSON 로드 영역 + 초기 XPToNextLevel 영역
XPToNextLevel = LevelXPTableLoader.GetXPToNextLevel(Level);
}
public void GainXP(int amount)
{
if (amount <= 0) return;
CurrentXP += amount;
while (CurrentXP >= XPToNextLevel)
{
CurrentXP -= XPToNextLevel;
Level++;
XPToNextLevel = LevelXPTableLoader.GetXPToNextLevel(Level);
OnLevelUp?.Invoke(Level);
}
}
}
```
### 6-5. 적 처치 시 XP
기본 = 5 (placeholder·코드 영역 잔존). 차기 영역 = 적 종류·등급별 JSON 테이블 (`enemy_xp_reward.json`) 분리 권고. BT12-Dev 본격 영역.
docs(BT12-MVP-A Phase 1): 경험치·레벨업·UI 설계 v1 + dev-auditor 감사 자성 + feedback 2종 신설 PD 직접 지시 2026-05-08 — 2건: 1. 적 처치 시 EXP 획득 + 레벨업마다 스킬 카드 3개 선택 기능 2. 레벨업 시 스킬 카드 선택 UI (스킬 효과 추후·UI만) PD 결정 (2026-05-08·"위 계획대로 진행"): (β) 채택 — BT12-Dev 보류 일부 해제·BT12-MVP-A 분리 항목 진행 dev-auditor 감사 자성 (Critical 2·Major 5): - Critical 1 Agent 라우팅 오류 — 본 PM이 dev-auditor에 개발팀장 직무 위임 (C23 위반) - Critical 2 BT12-Dev 보류 외연 무단 해석 (PD 명시 (β) 채택 후 정합) - Major 3 C49 Phase 1 주체 위반 / Major 4 PlayerStats 충돌 검토 누락 / Major 5 C50 표현 모호 정상 개발팀장 호출 시도 실패: - subagent_type=개발팀장 → "Agent type not found" - 시스템 카탈로그 한글 agent (개발팀장·기획팀장·클라이언트팀장·서버팀장) 미등재 발견 - PM 직접 처리 절충 (Opus·임시 개발팀장 역할 위임·C23 외연 자성) Phase 1 설계 산출: - 프로젝트/EerieVillage/개발/spec/BT12-MVP-A_설계_v1.md (신규·~600 라인) - §1 BT12-Dev v1 충돌·중복 매트릭스 (PlayerStats 분리·PlayerProgression 신규) - §2 신규 컴포넌트 7종 - §3~§5 통합 hook·이벤트 흐름·UI Prefab (PD 예시 정합) - §7 Phase 2 분량 옵션 (PM 권고 b 분할 ~150K) - §10 본 설계 자성 헌법급 feedback 2종 신설: - feedback_pm_auditor_role_conflation (감사관·팀장 분리·C23·C43·C48·C49) - feedback_korean_agent_catalog_unregistered (project tier·시스템 정정 의무) PD 지시 로그: - BT12-MVP-A 분리 항목 신규 등록 (활성·진행중) - BT12-Dev 본격 영역 = 보류 유지 (기획서 v0.3 확정 대기) 매니페스트: 2026-05-08_BT12MVPA_Phase1 archived Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 08:45:27 +00:00
---
## §7. Phase 2 분량 추정 (C50 사전 PD 승인 영역)
### 7-1. 신규 파일 (코드 7개·prefab 1개·asset 5장)
| 영역 | 파일 |
|------|------|
| Scripts/Progression | `PlayerProgression.cs`·`ExperienceSystem.cs`·`LevelUpManager.cs`·`SkillCardPlaceholder.cs`·`SkillCardPlaceholderPool.cs` (5 파일) |
| Scripts/UI | `SkillSelectionUI.cs`·`SkillCardSlot.cs` (2 파일) |
| Prefabs | `Assets/Prefabs/UI/SkillSelectionCanvas.prefab` (1 prefab — Canvas + 3 SkillCardSlot 자식) |
docs(BT12-MVP-A Phase 2-B asset 5 + 후속 정정): 설계서 §2-4 BT11 v0.2 정합 + PD Editor 가이드 + 대화로그 엔트리 10 EerieVillage 외부 레포 commit `755a51c` (asset 5 + meta 5 + folder meta 2 = 12 파일) 정합 + BurningTimes 후속 4 파일 산출물: - 설계서 v1 §2-4 + §7-1 정정 (P01·P12·AW01 한글명·id 정정·정정 이력 추가·기획팀 별도 안건 자진 고지) - BT12-MVP-A_Phase2B_PDEditor가이드.md (신규·B Prefab + C Scene 단계별·field 매핑·검증 영역·회귀 위험) - 대화로그 엔트리 10 (dev-team-lead 첫 정합 호출 + Sonnet 위임 + pm-auditor 검색 경로 오진 자성 + 통합 재감사 Pass) - 개발팀 PD 지시 로그 BT12-MVP-A 갱신 (Phase 2-B asset 5 산출물·PM 후속 대기 5종) C49 표준 - Phase 1 dev-team-lead Opus 첫 정합 + Phase 2 Sonnet 위임 + Phase 3 PM 검증 C42-7 + C44 - pm-auditor 검색 경로 오진 영역 본 PM 직접 재검증·실측 인용 정합 C35-9 매니페스트 등록 + pm-auditor 통합 재감사 Pass dev-team-lead 자진 고지 - 설계서 §2-4 BT11-Plan v0.2 정합 X 정정 적용 본 PM 자성 누적 3건: 1. dev-team-lead 호출 분량 추정 50~80K → 실제 116K (C50 정확도 ↑ 의무) 2. pm-auditor 의뢰문 외부 레포 경로 명시 부족 (정정 적용) 3. dev-team-lead Phase 1 자성 영역 본 PM BT11 v0.2 grep 검증 부족 pm-auditor 자체 자성 (Critical 자체 보고): - 직전 호출 영역 검색 경로 오진 (C5·C44·C42-D 위반) - 헌법급 feedback `feedback_pm_auditor_search_scope_external_repo` 신설 의무 (별도 commit) 후속 영역: - B (Prefab) + C (Scene) PD Editor 직접 작업 (가이드 정합) - Phase 3 dev-team-lead 통합 검증 - 기획팀 별도 안건 (`01_카드_풀.md` line 114 P12 = "도약강화" 정정)
2026-05-08 10:18:10 +00:00
| Data | `Assets/Data/SkillPlaceholders/{A01_jineonbu, A05_hagikjin, P01_bonghwanggyeok, P12_saengmyeongkkot, AW01_cheonbugyeongmun}.asset` (5 asset · 2026-05-08 정정 정합 — BT11-Plan v0.2 `02_스킬_효과_컨셉.md` 정합) |
docs(BT12-MVP-A Phase 1): 경험치·레벨업·UI 설계 v1 + dev-auditor 감사 자성 + feedback 2종 신설 PD 직접 지시 2026-05-08 — 2건: 1. 적 처치 시 EXP 획득 + 레벨업마다 스킬 카드 3개 선택 기능 2. 레벨업 시 스킬 카드 선택 UI (스킬 효과 추후·UI만) PD 결정 (2026-05-08·"위 계획대로 진행"): (β) 채택 — BT12-Dev 보류 일부 해제·BT12-MVP-A 분리 항목 진행 dev-auditor 감사 자성 (Critical 2·Major 5): - Critical 1 Agent 라우팅 오류 — 본 PM이 dev-auditor에 개발팀장 직무 위임 (C23 위반) - Critical 2 BT12-Dev 보류 외연 무단 해석 (PD 명시 (β) 채택 후 정합) - Major 3 C49 Phase 1 주체 위반 / Major 4 PlayerStats 충돌 검토 누락 / Major 5 C50 표현 모호 정상 개발팀장 호출 시도 실패: - subagent_type=개발팀장 → "Agent type not found" - 시스템 카탈로그 한글 agent (개발팀장·기획팀장·클라이언트팀장·서버팀장) 미등재 발견 - PM 직접 처리 절충 (Opus·임시 개발팀장 역할 위임·C23 외연 자성) Phase 1 설계 산출: - 프로젝트/EerieVillage/개발/spec/BT12-MVP-A_설계_v1.md (신규·~600 라인) - §1 BT12-Dev v1 충돌·중복 매트릭스 (PlayerStats 분리·PlayerProgression 신규) - §2 신규 컴포넌트 7종 - §3~§5 통합 hook·이벤트 흐름·UI Prefab (PD 예시 정합) - §7 Phase 2 분량 옵션 (PM 권고 b 분할 ~150K) - §10 본 설계 자성 헌법급 feedback 2종 신설: - feedback_pm_auditor_role_conflation (감사관·팀장 분리·C23·C43·C48·C49) - feedback_korean_agent_catalog_unregistered (project tier·시스템 정정 의무) PD 지시 로그: - BT12-MVP-A 분리 항목 신규 등록 (활성·진행중) - BT12-Dev 본격 영역 = 보류 유지 (기획서 v0.3 확정 대기) 매니페스트: 2026-05-08_BT12MVPA_Phase1 archived Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 08:45:27 +00:00
### 7-2. 기존 파일 수정 (3 파일)
| 파일 | 변경 |
|------|------|
| `EnemyDeath.cs` (Gameplay) | `Execute` 영역 마지막 ExperienceSystem 호출 1줄 |
| `PlayerController.cs` | Awake 영역 PlayerProgression 자동 부착 1줄 |
| `Ingame.unity` (Scene) | `[LevelUpManager]` GameObject 신규 + SkillSelectionCanvas 부착 |
### 7-3. 토큰 추정
| Phase 2 옵션 | 분량 |
|-----|-----|
| **(a) 단일 Task 통합** (코드 7 + UI prefab + asset 5 + Scene 통합) | ~120~180K |
| **(b) Phase 2-A 시스템 코드 + Phase 2-B UI prefab/asset 분리** | 2-A ~70K + 2-B ~80K = ~150K (분산) |
| **(c) 3분할** (Phase 2-A 코드만·Phase 2-B placeholder asset·Phase 2-C UI prefab) | 2-A ~60K + 2-B ~40K + 2-C ~60K = ~160K (분산) |
**개발팀장(임시 PM 위임) 권고 = (b)**. 사유:
- 시스템 코드 영역과 UI prefab 영역 = 직무 분리 명확
- 코드 영역 검증 후 UI 영역 진행 = 회귀 위험 감소
- 단일 Task 영역 분산 회피
### 7-4. Phase 3 검증 항목
- 회귀: BT5-Dev 발판·몬스터 시스템 영역 영향 검증 (EnemyDeath 영역 변경)
- BT7-Dev VS 순수형 자동 발동 영역 영향 검증 (ExperienceSystem 신규 호출 영역)
- BT12-Dev v1 영역 충돌 X 검증 (PlayerStats 분리 정합)
- UI 영역 PD 예시 정합 검증 (색상·레이아웃·인터랙션)
- Time.timeScale = 0 영역 UI 인터랙션 정합 검증 (unscaledDeltaTime)
---
## §8. 회귀 위험 영역
| 영역 | 위험도 | 검증 방법 |
|------|------|---------|
| `EnemyDeath.Execute` 마지막 호출 추가 | 낮음 | EnemyDeath 영역 기존 호출 그대로 + 본 호출 마지막 추가 |
| `PlayerController.Awake` PlayerProgression 부착 | 낮음 | 자동 GetOrAdd 패턴 (기존 PlayerInvulnerabilityFlash 영역 정합) |
| Time.timeScale = 0 영역 | 중 | Animator 영역 영향 (Animator.updateMode = UnscaledTime 권고) · 다른 시스템 영향 검증 |
| Scene 영역 [LevelUpManager] + SkillSelectionCanvas 추가 | 낮음 | Scene yaml 영역 신규 GameObject 추가 (기존 영역 변경 X) |
| BT5-Dev #111 좁은 발판 patrol 영역 | 미영향 | 본 작업 영역 EnemyController 영역 변경 X |
---
## §9. 기각안 (Phase 1 설계 영역)
| # | 안 | 채택 결정 | 사유 |
|---|---|---------|------|
| 1 | `PlayerStats` 영역 직접 확장 (Level·EXP 추가) | **기각** | BT12-Dev v1 영역 변경 = 충돌 위험·차기 본격 착수 시점 영향 |
| 2 | `ScriptableObject 3종 (ActiveSkillData 등)` 활용 | **기각** | 효과 영역 정의 X (PD 명시 "기능 추후") = 기존 ScriptableObject 영역 직무 부합 X |
| 3 | `PlayerSkillInventory` 활용 | **기각** | 60종 카드 효과 영역 = 차기 본격. 본 작업 영역 = UI 닫기만 |
| 4 | `Schedule<PlayerLeveledUp>` Simulation 이벤트 | **검토 후 채택** | 기존 `Schedule<T>` 패턴 정합. C# event 패턴과 절충 — 본 설계 = C# event (간단·외부 시스템 의존 X) |
| 5 | UI 즉시 적용 (확인 버튼 X·VS 표준) | **기각** | PD 예시 영역 명확 — 확인 버튼 단계 추가 |
---
## §10. 본 설계 자성 (C23 외연·시스템 한계)
본 설계 = **총괄PM 임시 개발팀장 역할 위임 산출**. 정상 개발팀장 agent 시스템 카탈로그 미등재 영역 한계 절충.
**의무 영역**:
1. Phase 3 검증 시점 dev-auditor 감사 의무 (본 산출물 정합·BT12-Dev v1 영역 충돌 검증)
2. 시스템 카탈로그 한글 agent 등재 정정 (`feedback_korean_agent_catalog_unregistered.md` 신설)
3. `feedback_pm_auditor_role_conflation.md` 신설 — 본 PM이 직전 dev-auditor 호출 시 Critical 1 (라우팅 오류) 자성
---
**작성**: 총괄PM (임시 개발팀장 역할 위임 — Phase 1 설계)
**일자**: 2026-05-08
**관련 규칙**: C23 (역할 연기 자성)·C36 (PM 자율 외연 자성)·C39 (시스템 반영 실측)·C42 (사전 검증)·C43 (호칭 라우팅)·C49 Phase 1·C50 (사전 PD 승인)
**Phase 2 진행 = PD 승인 후**