179 lines
10 KiB
Markdown
179 lines
10 KiB
Markdown
|
|
---
|
||
|
|
type: 설계문서
|
||
|
|
project: 수상한잡화점
|
||
|
|
subject: 독립 시뮬레이터 아키텍처 (Unity MCP 실행 인프라)
|
||
|
|
version: v1
|
||
|
|
date: 2026-04-17
|
||
|
|
status: 초판
|
||
|
|
author: 개발팀장
|
||
|
|
related:
|
||
|
|
- 공유/소통/개발팀→PM/2026-04-17_Phase0-C_QP2_정밀2차_응답서.md
|
||
|
|
- 프로젝트/수상한잡화점/시뮬레이터/02_시나리오_JSON_스키마_v1.md
|
||
|
|
- 프로젝트/수상한잡화점/시뮬레이터/03_결과_JSON_포맷_v1.md
|
||
|
|
- 프로젝트/수상한잡화점/시뮬레이터/04_MCP_호출_스니펫_v1.md
|
||
|
|
핵심원칙:
|
||
|
|
- 기존 수상한잡화점 코드 일체 수정 금지
|
||
|
|
- 독립 어셈블리 격리 (`NerdNavis.Sim.asmdef`)
|
||
|
|
- Editor-only (빌드 산출물 제외)
|
||
|
|
- 메커닉은 별도 모델로 독립 재구현 (Read-only 참조)
|
||
|
|
---
|
||
|
|
|
||
|
|
# 독립 시뮬레이터 아키텍처 v1
|
||
|
|
|
||
|
|
## 1. 배경 (왜 필요한가)
|
||
|
|
|
||
|
|
### 1-1. PD님 직접 지시 (2026-04-17)
|
||
|
|
> "기존 수상한잡화점 프로젝트의 코드나 구조에 영향을 주지 않는 독립적인 시뮬레이터로 동작해야 함."
|
||
|
|
|
||
|
|
### 1-2. 요구사항 해석
|
||
|
|
1. **기존 코드 불변 원칙**: `Assets/Script/` 하위 파일을 일절 수정 불가. 시뮬 인프라는 **관찰·참조**만 허용, **수정·확장·상속**을 통한 침투 불허
|
||
|
|
2. **독립 어셈블리 격리**: 기존 `Assets/Script/*.asmdef`와 별개 어셈블리로 운영하여 빌드 의존성·컴파일 영향 차단
|
||
|
|
3. **Editor-only 동작**: 프로덕션 빌드 산출물에 시뮬 코드 포함 방지 (앱 크기·보안·의도치 않은 실행 차단)
|
||
|
|
4. **메커닉 재현의 독립성**: Actor·Effect 등의 로직을 재사용·복제가 아닌 **동등 결과를 내는 별도 로직**으로 독립 재구현
|
||
|
|
|
||
|
|
### 1-3. 설계 제약 (대안 고려)
|
||
|
|
- **대안 A (기각)**: 기존 `Assets/Script/Actor/` 직접 호출하여 시뮬 실행 → 코드 수정 위험·PlayMode 의존·PD 제약 위반
|
||
|
|
- **대안 B (기각)**: 별도 레포 구축 → Unity MCP `execute_code`가 현 프로젝트 내부만 접근 가능, 운영 분리 과도
|
||
|
|
- **대안 C (채택)**: 같은 Unity 프로젝트 내 `Assets/Sim/` 신규 폴더 + 독립 asmdef + Editor-only define + 모델 독립 재구현
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 2. 폴더·어셈블리 구조
|
||
|
|
|
||
|
|
```
|
||
|
|
D:/NerdNavis/FilGoodBandits/DeckBuilding/Assets/Sim/ ← 신규 (이번에 생성)
|
||
|
|
├── NerdNavis.Sim.asmdef ← 독립 어셈블리 정의
|
||
|
|
├── Runtime/
|
||
|
|
│ ├── SimulationRunner.cs ← 진입점
|
||
|
|
│ ├── ScenarioLoader.cs ← 시나리오 JSON → ActorModel 로드
|
||
|
|
│ ├── ResultEmitter.cs ← 결과 JSON 출력
|
||
|
|
│ └── Models/
|
||
|
|
│ ├── ActorModel.cs ← Actor 동등 모델 (독립 재구현)
|
||
|
|
│ ├── DefenceModel.cs ← 터치 방어 30% + 지속형 재현
|
||
|
|
│ └── DamageCalc.cs ← 데미지 감소 pipeline 재현
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2-1. 어셈블리 정의 (`NerdNavis.Sim.asmdef`)
|
||
|
|
- `name`: `NerdNavis.Sim`
|
||
|
|
- `rootNamespace`: `NerdNavis.Sim`
|
||
|
|
- `references`: **비움** (기존 어셈블리 참조 안 함 — 독립성 확보)
|
||
|
|
- `includePlatforms`: `["Editor"]` (Editor-only)
|
||
|
|
- `excludePlatforms`: `[]`
|
||
|
|
- `autoReferenced`: `false`
|
||
|
|
- `defineConstraints`: `["UNITY_EDITOR"]`
|
||
|
|
- `noEngineReferences`: `false` (UnityEngine은 사용, but 최소)
|
||
|
|
|
||
|
|
### 2-2. 의존성 격리 결과
|
||
|
|
- 빌드 시 본 어셈블리 **자동 제외** (Editor 플랫폼만 타겟)
|
||
|
|
- 기존 게임 어셈블리와 컴파일 단위 분리 → 기존 코드 변경 감지 없음
|
||
|
|
- 기존 `Assets/Script/` 전혀 참조하지 않으므로 기존 리팩토링·삭제에도 영향 없음
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 3. 실행 흐름
|
||
|
|
|
||
|
|
```
|
||
|
|
기획팀장 Unity MCP SimulationRunner
|
||
|
|
│ │ │
|
||
|
|
│ 04_MCP_호출_스니펫_v1.md 기반 │ │
|
||
|
|
│ execute_code 호출 │ │
|
||
|
|
│ {scenario_json_path: "..."} │ │
|
||
|
|
│ │ │
|
||
|
|
│ ─────────────────────────────► │ │
|
||
|
|
│ │ │
|
||
|
|
│ │ SimulationRunner.Run(path)
|
||
|
|
│ │ ─────────────────────────►
|
||
|
|
│ │ │
|
||
|
|
│ │ │ 1. ScenarioLoader.Load(path)
|
||
|
|
│ │ │ → ActorModel 생성
|
||
|
|
│ │ │ 2. 전투 tick 루프 실행
|
||
|
|
│ │ │ (DefenceModel·DamageCalc 호출)
|
||
|
|
│ │ │ 3. ResultEmitter.Emit(result)
|
||
|
|
│ │ │ → 결과 JSON 파일 또는 stdout
|
||
|
|
│ │ │
|
||
|
|
│ │ ◄─────────────────────────
|
||
|
|
│ │ {결과 JSON}
|
||
|
|
│ ◄───────────────────────────── │
|
||
|
|
│ │ │
|
||
|
|
│ 기획팀 분석·밸런스 튜닝 │ │
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3-1. 실행 환경 2모드
|
||
|
|
- **모드 1 (단일 실행)**: Unity Editor 기동 상태 + MCP 연결 + `execute_code` 한 번 → 결과 1건
|
||
|
|
- **모드 2 (배치 실행)**: `execute_code`로 스윕 파라미터 배열 전달 → 내부 루프로 N회 실행 + 결과 N건 집계
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. 독립 모델 설계 (Models/)
|
||
|
|
|
||
|
|
### 4-1. ActorModel
|
||
|
|
**기존 `Actor.cs`(4545줄)를 재구현하지 않는다.** 시뮬에 필요한 최소 상태만 추출:
|
||
|
|
|
||
|
|
```csharp
|
||
|
|
public class ActorModel {
|
||
|
|
public string id;
|
||
|
|
public float maxHP, hp;
|
||
|
|
public float shield;
|
||
|
|
public float attackDmg;
|
||
|
|
public float attackCoolTime;
|
||
|
|
public float accumulatedAttackTime;
|
||
|
|
public bool isDefencing; // ActorStatus == Defecne 동등
|
||
|
|
public bool isDead => hp <= 0f;
|
||
|
|
// ... 시뮬 범위 내 최소 필드만
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4-2. DefenceModel (실측 규칙 재현)
|
||
|
|
Q-P2 정밀 2차 응답서 §2 실측 기반 독립 구현:
|
||
|
|
- `PCDefence_Mul = 0.3f` (30% 감소)
|
||
|
|
- `PCDefence = 1` (절대값 1 감소)
|
||
|
|
- 터치 Down↔Up 지속 (`isDefencing` 플래그)
|
||
|
|
- 방어 중 공격 불가 (`accumulatedAttackTime` 갱신 중단)
|
||
|
|
- 방어 중 데미지: `dmg = (dmg - 1) * (1 - 0.3)` (추가 감소 스택은 포함하지 않음 — 단순화)
|
||
|
|
|
||
|
|
### 4-3. DamageCalc (감소 pipeline 재현)
|
||
|
|
`Actor.cs:762-809` 실측 기반 간이 재구현. 시뮬 범위 외(카드·인장·각성)는 제외하고 **순수 방어 메커닉 + 기본 스탯** 차원만 재현. 복잡 메커닉 필요 시 scope 확장 v2에서 추가.
|
||
|
|
|
||
|
|
### 4-4. 재구현 원칙
|
||
|
|
- **동등 결과 우선, 구조 복사 금지** — 기존 코드를 복붙하지 않고 실측 스펙을 문서로 보고 재작성
|
||
|
|
- **최소 기능 원칙** — 밸런싱에 필요한 축(HP·Shield·Dmg·Defence·CoolTime)만 구현, 나머지는 생략
|
||
|
|
- **버전 고정 주석** — 각 파일 상단에 `// 실측 기준: Dev 브랜치 43b6074c4 (2026-04-17)` 명시하여 원본 변경 시 재동기화 시점 명확화
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 5. 검증 방법
|
||
|
|
|
||
|
|
### 5-1. 기존 코드 불변 증명
|
||
|
|
- 본 작업 커밋 diff에 `Assets/Script/` 하위 변경이 **0건**이어야 한다
|
||
|
|
- `git diff --stat Assets/Script/` 결과가 비어있는지 확인
|
||
|
|
|
||
|
|
### 5-2. 빌드 제외 증명
|
||
|
|
- `manage_build` MCP로 Player 빌드 시도 → 빌드 로그에 `NerdNavis.Sim` 미포함 확인
|
||
|
|
- `NerdNavis.Sim.asmdef`의 `includePlatforms: ["Editor"]` 준수
|
||
|
|
|
||
|
|
### 5-3. 메커닉 등가성 검증 (향후)
|
||
|
|
- 동일 시나리오에서 실제 게임 PlayMode vs 시뮬 실행 결과를 **기획팀이 비교** → 오차 10% 이내 목표
|
||
|
|
- 오차 원인이 시뮬 모델 누락인지 실측 데이터 누락인지 구분하여 보완
|
||
|
|
|
||
|
|
### 5-4. MCP 연결 필요 환경
|
||
|
|
- 본 세션에서 **Unity MCP 접근 가능 여부 미확인** (C23 정직: `mcp__unity-mcp__*` 호출을 실제로 수행하지 않음). 스켈레톤 코드는 작성 완료 상태이며, Unity Editor 구동 + MCP 연결 시점에 기획팀장·개발팀이 실행 검증
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 6. 확장 포인트 (v2 이후)
|
||
|
|
|
||
|
|
1. **카드·인장·각성 효과 모델 추가** — 현재 스코프는 방어 메커닉 중심. 기획팀이 밸런싱 축 확장 요청 시 Models/에 파일 추가
|
||
|
|
2. **몬스터 AI 모델** — 현재 단순 공격 tick만. 라인별 공격 조건·특수 효과(자폭·치명타 등) 재현 필요 시 `MonsterAIModel.cs` 추가
|
||
|
|
3. **앵커 전투 노드 시퀀스 통합** — 단일 전투가 아닌 스테이지 경로 전체 시뮬
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 7. 변경 이력
|
||
|
|
- **v1 (2026-04-17)**: 초판. PD 지시 #37 독립 시뮬 제약에 따른 어셈블리 격리 아키텍처.
|
||
|
|
|
||
|
|
## 8. 기각안 (P24)
|
||
|
|
- **기각안 A**: `AssemblyDefinitionReferences` 로 기존 `Assets/Script/` 어셈블리 참조 → 독립성 훼손, PD 제약 위반. 0 references 고수
|
||
|
|
- **기각안 B**: Runtime 포함(Editor-only 제외) → 빌드 산출물 오염·보안. Editor-only 확정
|
||
|
|
- **기각안 C**: `Assets/Editor/Sim/` 아래 배치 → Unity asmdef 자동 Editor 어셈블리와 충돌 위험. `Assets/Sim/Runtime/` + 자체 asmdef의 Editor 플랫폼 제약이 깔끔
|
||
|
|
- **기각안 D**: 별도 레포 서브모듈 → Unity MCP `execute_code` 경로 접근 제약·기획팀 셋업 복잡도 증가. 동일 레포 격리가 최선
|