← 자료실/designsLOW

Sp02 W2 — DOTS 측정 트리거 + Blob 변환 후보 평가 명세서

designs/sp02-w2-dots-measurement-spec.md

Sp02 W2 — DOTS 측정 트리거 + Blob 변환 후보 평가 명세서

작성: 2026-05-02 (dots-platform / 류재현) · 근거: designs/sprint-02-w2-prestige-tech-sketch.md v1.0 APPROVED · designs/sprint-01-w2-importer-design.md v1.0 APPROVED · sprints/phase-2-roadmap-2026-04-21.md v2.0 APPROVED 문서 상태: v1.0 (PD 옵션 A 승인 2026-05-02 → 즉시 작성) 범위: Sp02 W2 (2026-05-25 ~ 2026-05-31, 로드맵 W6) 동안 code-lead 정현우의 PR 5건 (W6-T01~T05) 에 대한 측정 트리거 정량 기준 + DOTS Blob 변환 후보 4건 평가 + 분업 경계 표 수치 경계: 본 문서는 측정·진단·역할 분담만. 게임 밸런스 / SO 카탈로그 스키마 / 런타임 시그니처는 기존 APPROVED 설계 인용 외 신규 결정 0건 (code-lead / game-designer 영역). --- ## 0. 한 줄 맥락 (PD 30초) Sp02 W2 = 프레스티지 런타임 (struct + List + JSON + 6훅) 머지 주차. 본 명세는 "측정 우선, 변환 보수적" 입장: T1~T4 정량 트리거 4축 + 4 변환 후보 평가 결과 = Sp02 W2 시점 변환 후보 0건 (모두 < 100 엔트리, 단일 유저). 단 W6-T04 BuildSummary 1Hz vs 매프레임 은 핵심 게이트 (code-lead 사전 검토 1h 권장). 본격 DOTS 합류는 Sp03 IdleTicker 시점.

§1. 측정 트리거 정량 기준 (4축 표)

§1.1 4축 정의

축지표임계측정 도구판정 우선도
T1 호출 빈도단일 메서드 호출 / frame> 10,000 / frame (16.6ms 기준 = 600,000 calls/sec)Profiler CPU Hierarchy Self ms + Calls 컬럼High
T2 GC allocMono allocation / sec> 1 KB / sec (5초 평균) 또는 Gen0 GC > 5회 / minProfiler Memory Module GC Allocated In FrameHigh
T3 FPS dropframe time 95-percentile> 16.6 ms (60fps 기준) — Editor Standalone 동시 측정Profiler CPU PlayerLoop total + frame chartMid
T4 Heap fragmentationMono heap 사용량Reserved > 50 MB 또는 Reserved/Used 비율 > 30%Memory Profiler 패키지 Mono Heap 분석Low

§1.2 판정 규칙 (조합)

판정 = High  : T1 충족 + T2 충족 (동시)
판정 = Mid   : T3 단독 충족 (T1·T2 미충족)
판정 = Low   : T4 단독 충족 (Sp03 이월 검토)
판정 = None  : 모두 미충족 (변환 불필요, 현재 코드 유지)

§1.3 임계값 근거


§2. 측정 도구 + Sp02 W2 워크플로우

§2.1 주 도구 = Unity Profiler (CPU / Memory / Rendering 3 모듈)

§2.2 보조 = Unity Memory Profiler 패키지

§2.3 Frame Debugger = Sp02 범위 외

§2.4 워크플로우 4단계 (PR 머지 전 표준 절차)

Step 1. PR 머지 직전 (code-lead) 또는 직후 (dots-platform 사후 검증)
Step 2. Unity Editor → Play Mode → Profiler 활성화 (Window > Analysis > Profiler)
Step 3. 30초 실행 (idle 10초 + 스폰 / 입력 / Spend 호출 10초 + idle 10초)
Step 4. CPU Hierarchy → Self ms 내림차순 → Top 5 메서드 캡처 (스크린샷 + 수치 기록)
       Memory Module → GC Allocated In Frame 5초 평균 + Mono Heap Reserved 캡처
       T1~T4 각 축 충족 여부 판정 (§1.2 규칙)
       판정 = High / Mid → PR 코멘트에 측정값 + 판정 + 후속 조치 명시
       판정 = None → PR 머지 OK

Sp02 W2 측정 책임자:


§3. 측정 시점 명세 (Sp02 W2 PR 분기)

§3.1 Sp02 W2 PR 5건 분기 표 (W6-T01 ~ W6-T05)

PR ID작업신규 코드 영역측정 트리거 우선 축code-lead 자가 측정 충분?dots-platform 사전 검토?
W6-T01TsvReader.cs 공통화 (Sp01 W2 DQ3 이월)Assets/Editor/Importers/Shared/TsvReader.csT2 (Editor only, 30~60행 파싱 시 alloc)✅ 충분❌ 불필요 (Editor 코드, 런타임 영향 0)
W6-T02PrestigeItemImporter.cs 신규 (TsvReader 첫 소비자)Assets/Editor/Importers/PrestigeItemImporter.csT2 (Editor only)✅ 충분❌ 불필요
W6-T03PlayerPrestigeState.cs (struct + List) + PrestigeSlot.csAssets/_Project/Scripts/Runtime/Prestige/T1 (Spend / RefundAll 호출 빈도) + T2 (List Add alloc)✅ 충분⚠️ 권고: 1h 사전 검토 — _slots = new List<PrestigeSlot>(60) capacity 미지정 시 List 내부 array 재할당 (T2 위반 가능)
W6-T04PrestigeCalculator.SummarizeChannel + BuildSummaryAssets/_Project/Scripts/Runtime/Prestige/PrestigeCalculator.csT1 (매프레임 호출 위험) + T2 (struct 반환 boxing)❌ 부족✅ 필수 (§3.2 핵심 게이트, 사전 1h)
W6-T05PrestigeSaveService (JSON) + 이벤트 훅 6개 활성화Assets/_Project/Scripts/Runtime/Prestige/PrestigeSaveService.cs + PrestigePpAccumulator.csT2 (JsonUtility alloc, Save 시 string.Concat)✅ 충분❌ 불필요 (1초 디바운스 + 게임 종료 flush 구조 = 호출 빈도 낮음)

§3.2 핵심 게이트 = W6-T04 (BuildSummary 1Hz vs 매프레임 호출 차단)

리스크:

code-lead 사전 검토 1h 권장 사항 (dots-platform → code-lead 인수인계):

  1. BuildSummary 호출 트리거 = 이벤트 기반만 허용 (OnSlotChanged / OnPpChanged 발화 시만 재계산). Update() 내 매프레임 호출 금지.
  2. UI 레이어가 BuildSummary 결과를 캐싱 (_lastSummary 필드). 이벤트 발화 전까지 캐시 사용.
  3. SummarizeChannel 내부 slots.Where(s => s.channel == channel) 같은 LINQ 사용 금지 (enumerator alloc 매 호출 16~32 B). 명시적 for 루프.
  4. BuildSummary 필드는 Sp02 W1 game-designer 확정 stat key 집합 (예: AtkPct, CritRate, DropPct, ...) 만 포함. Sp03 Stat 시스템 확정 후 1차 동결 (Sp02 W2 시점 6 필드 추정).

측정 스크립트 (Sp02 W2 D-2, 2026-05-29 권장):

[전제] Editor Play Mode + 60 슬롯 데이터 시드
[Action] 1초 동안 Spend 10회 호출 (이벤트 발화 10회 → SummarizeChannel 10회 호출)
[기대] CPU Hierarchy → SummarizeChannel.Self ms < 0.1 ms × 10 calls = 1ms total
       GC Allocated In Frame < 100 B / sec
[위반 시] dots-platform 즉시 호출 → 캐싱 / 부분 갱신 알고리즘 / Blob 4지선다 (§5)

§3.3 W6-T01 ~ W6-T05 측정 일정 (Sp02 W2 5/25 ~ 5/31)

일자작업측정
5/25 (월)W6-T01 PR 작성 + 머지code-lead 자가 측정 (5분)
5/26 (화)W6-T02 PR 작성 + 머지code-lead 자가 측정 (5분)
5/27 (수)W6-T03 PR 작성 (사전 1h dots-platform 검토 권고)code-lead 자가 + dots-platform 사전 1h
5/28 (목)W6-T03 PR 머지 + W6-T04 PR 작성 시작-
5/29 (금)W6-T04 PR 머지 직전 측정 (§3.2 스크립트 실행)dots-platform 필수 측정 1h + 검토 1h
5/30 (토)W6-T05 PR 작성 + 머지code-lead 자가 측정
5/31 (일)Sp02 W2 회고 + Sp03 킥오프 D-1dots-platform Sp03 합류 사전 동기화 1h

§4. DOTS Blob 변환 후보 평가 (4건)

§4.1 후보 1: DropRateTableSO Dictionary 60엔트리

§4.2 후보 2: AffixPoolSO List 6 엔트리 (Sp02 W2) → 36 엔트리 (Sp04)

§4.3 후보 3: PrestigeItemCatalogSO List 30 엔트리

§4.4 후보 4: PlayerPrestigeState._slots List 60 (Sp02 W2 핵심)

§4.5 결론: Sp02 W2 시점 변환 후보 = 0건

후보Sp02 W2 판정변환 결정재측정 시점
§4.1 DropRateTableSO 60 엔트리None (Low)유지Sp06+ 1만 mob 시뮬
§4.2 AffixPoolSO 6→36 엔트리None (Low)유지Sp04 36행 머지 시
§4.3 PrestigeItemCatalogSO 30 엔트리None (Low)유지(변경 사유 없음)
§4.4 PlayerPrestigeState._slots 60None (Mid 조건부, capacity 권고)유지Sp06+ Follower / 멀티 캐릭터

Sp03 DOTS 사전 호환 = 이미 반영:


§5. 호출 절차 (트리거 충족 시 5단계)

§5.1 Step 1 = code-lead 측정 보고

  1. Profiler CPU Hierarchy 스크린샷 (Top 5 Self ms)
  2. Profiler Memory GC Allocated In Frame 5초 평균 스크린샷
  3. T1 ~ T4 각 축 수치 + 판정 (예: T1 = 12,000 / frame ✅ High)
  4. 의심 메서드 / 호출 경로 (call graph)

§5.2 Step 2 = PD 결정 (dots-platform 호출 승인)

§5.3 Step 3 = dots-platform 호출 (측정 재현 1~2h)

§5.4 Step 4 = 변환 의사결정 (4지선다)

옵션적용 조건비용효과
(a) Blob 전환T1 ≫ 임계 + 데이터 read-only + 60 엔트리 초과8~16h캐시 친화 + GC 0
(b) 캐싱이벤트 기반 갱신 가능 + 결과 재사용 빈도 높음2~4h호출 빈도 90% 절감
(c) 알고리즘순회 / 정렬 / LINQ 남용 패턴1~3hO(N) → O(log N) 또는 enumerator 제거
(d) no-op측정 오류 / 환경 차이 / 임계 재산정 합의0hPR 머지 OK

기본 선호 순서: (d) → (c) → (b) → (a). DOTS 변환은 마지막 수단.

§5.5 Step 5 = PR 분리 + 머지 권한


§6. 분업 경계 (code-lead vs dots-platform 표)

§6.1 Sp02 W2 분업 표

영역code-lead (정현우)dots-platform (류재현)비고
Assets/Editor/Importers/Shared/TsvReader.cs (W6-T01)✅ 작성 / 머지❌ 손대지 않음Editor 코드, 런타임 영향 0
Assets/Editor/Importers/PrestigeItemImporter.cs (W6-T02)✅ 작성 / 머지❌ 손대지 않음TsvReader 첫 소비자
Assets/_Project/Scripts/Data/PrestigeItemCatalogSO.cs✅ 작성 / 머지❌ 손대지 않음SO 카탈로그, read-only
Assets/_Project/Scripts/Runtime/Prestige/PrestigeSlot.cs (W6-T03)✅ 작성 / 머지⚠️ 사전 1h 검토 (struct 필드 / blittable 보장 / capacity 권고)DOTS 1:1 이식 친화 보장
Assets/_Project/Scripts/Runtime/Prestige/PlayerPrestigeState.cs (W6-T03)✅ 작성 / 머지⚠️ 사전 1h 검토 (capacity 명시 권고)_slots List(60) capacity
Assets/_Project/Scripts/Runtime/Prestige/PrestigeCalculator.cs (W6-T04)✅ 작성 / 머지✅ 사전 1h 검토 + 머지 직전 1h 측정 필수핵심 게이트 (§3.2)
Assets/_Project/Scripts/Runtime/Prestige/PrestigeSaveService.cs (W6-T05)✅ 작성 / 머지❌ 손대지 않음JSON 저장, 디바운스 구조로 호출 빈도 낮음
Assets/_Project/Scripts/Runtime/Prestige/PrestigePpAccumulator.cs (W6-T05)✅ 작성 / 머지❌ 손대지 않음이벤트 핸들러 6개
Assets/_Project/Tests/Editor/Prestige*Tests.cs (7건)✅ 작성 / 머지❌ 손대지 않음code-lead 테스트 영역
Unity6/Packages/manifest.json (Memory Profiler 패키지 추가)✅ 결정 권한⚠️ 추가 권고만 (Sp02 W2 시점 권고 0건)패키지 변경 = code-lead 영역

§6.2 침범 금지선 (dots-platform 자기 제약)

  1. 류재현은 Sp02 W2 메인 코드 PR 자체에 손대지 않음. 모든 PR = code-lead 작성 / 머지.
  2. 검토 / 측정 / 권고만 제공. 코드 직접 수정은 PD 명시 승인 필수.
  3. Sp02 W2 시점 DOTS 변환 PR 0건 목표. 측정 결과 None 판정이면 dots-platform 자체 변환 욕심 차단.
  4. sketch 문서 (sprint-02-w2-prestige-tech-sketch.md) 직접 수정 금지 — code-lead 영역. 측정 결과는 본 명세서 (sp02-w2-dots-measurement-spec.md) 갱신 또는 PR 코멘트로만.
  5. game-designer / graphics-lead / 마케팅 영역 의견 X — 수치 / 시각 / BM 의견 0건.

§6.3 Sp03 IdleTicker DOTS 전환 = 류재현 본격 합류 시점


§7. 분량 · 결정 추적


§8. 부록 — 측정 결과 기록 양식 (Sp02 W2 D+14 회고용)

[PR ID] W6-T0X
[측정 일시] 2026-05-XX HH:MM
[측정자] code-lead / dots-platform
[T1 호출 빈도] XXX / frame  → 판정: None / Mid / High
[T2 GC alloc]  XXX B / sec  → 판정: None / Mid / High
[T3 frame 95p] XX.X ms       → 판정: None / Mid / High
[T4 Mono Heap] Reserved XX MB / Used XX MB → 판정: None / Mid / High
[종합 판정] None / Mid / High
[조치] 없음 / 캐싱 / 알고리즘 / Blob 전환 / 측정 재현
[Sp03 합류 인수인계] (있을 경우 1줄)

(끝 — v1.0, 2026-05-02 dots-platform 작성, PD 옵션 A 승인 후 즉시 작성)