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

24 KiB
Raw Blame History

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)

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 (정적 게이트웨이)

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 싱글톤)

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)

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장)

Placeholder 카드 5장 (BT11-Plan v0.2 영역 추출):

ID 한글명 등급 설명 (placeholder)
A01_jineonbu 진언부 Common 전방 직선 투사체. 가장 기본 패턴.
A05_hagikjin 학익진 Common 부채꼴 전방 자동 타격. 밀집 구간 특효.
P01_giryeon 기 단련 Common 모든 공격 대미지 증가.
P12_bangho 방호 Rare 최대 하트 1 증가 + 즉시 회복.
AW01_jineonjingyeong 진언경 (각성) Max 진언부 진화 — 다중 투사체 + 추적.

2-5. SkillCardPlaceholderPool (MonoBehaviour)

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)

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 — 단일 카드 표시)

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 영역 경험치 발급

// 기존 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 영역 자동 부착

// 기존 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 영역 정합

balance/02 v0.2 §3 영역 EXP 곡선 = XPToNextLevel(L) = 80 + L × 20.

  • Lv 1 → Lv 2: 100 XP
  • Lv 2 → Lv 3: 120 XP
  • ...
  • Lv 10 → Lv 11: 280 XP

본 설계 §2-1 ComputeXPToNextLevel 영역 정합. balance-designer 영역 추후 정정 가능.

적 처치 시 XP 영역 = 기본 5. 차기 영역 = 적 종류·등급별 차등 (BT12-Dev 본격 영역).


§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 자식)
Data Assets/Data/SkillPlaceholders/{A01_jineonbu, A05_hagikjin, P01_giryeon, P12_bangho, AW01_jineonjingyeong}.asset (5 asset)

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 승인 후