3.6 KiB
3.6 KiB
작업 로그: Combat Level Design — Time-Based Difficulty Scaling 구현
📋 작업 내용 (What)
"전투 타임라인 & 난이도 프로토콜" 설계안을 기반으로 Skybound 프로젝트의 StageDirectorSystem, SpawnerSystem, EngineProtocol을 업그레이드하고, 신규 CombatTimeline 설정 파일을 추가함.
🎯 왜 했는지 (Why)
기존 스테이지 시스템의 문제점:
- StageDirectorSystem: 하드코딩된
if frame >= X체이닝, 새 phase 추가 불가 - SpawnerSystem: 완전 무작위 스폰 → 스파이크 없음, 긴장감 없음
- 난이도 곡선 부재: 적 HP 단순 배율만 존재, 밀도/타이밍 변화 없음
- Death Trap 발생 가능: EVO 준비 없이 Spike 구간 진입
💡 기대값 (Expected Value)
- 시간(초) 기반 스크립티드 웨이브 등장 (STANDARD 15분 / BLITZ 8분)
- 페이즈별 difficultyMult / spawnIntervalMult 자동 동기화
- Spike 30초 전 자동 EXP 젬 밀도 2배 부스트 (Death Trap Avoidance)
- 스웜 구간에서 최대 6유닛씩 3프레임 간격 분산 스폰 (성능 보장)
- 보스 처치 후 영구 성장 보상 발행 (UX Continuity)
- TypeScript 에러 0개
🔧 처리 과정 (How)
1. CombatTimeline.ts (신규 생성)
- StageMode: STANDARD(15분) / BLITZ(8분)
- DifficultyPhase: name, startSec, diffMult, spawnIntervalMult, maxEnemyCount, bgmCue
- WaveTrigger: triggerSec, enemyType, density, isSpike, eventEffect, comms, shake
- STANDARD_TIMELINE: 5개 페이즈, 15개 WaveTrigger (Spike 4회)
- BLITZ_TIMELINE: 5개 페이즈, 10개 WaveTrigger (Spike 6회)
- 유틸 함수: getActivePhase(), collectDueTriggers(), getTimeline()
2. StageDirectorSystem.ts (전면 재작성 v2.0)
- tickTimeline(): 매 프레임 currentSec = frame/60로 getActivePhase() 및 collectDueTriggers() 호출
- 페이즈 자동 전환: activePhase.name !== phase일 때 STAGE_TRANSITION 인텐트 발행
- difficultyMult / tensionLevel: activePhase.diffMult + densityFactor로 자동 동기화
- EXP 밀도 부스트: 다음 Spike까지 30초 이내 시 EXP_DENSITY_BOOST 인텐트 발행
- processTriggers(): WaveTrigger → 이벤트(COMMS, SCREEN_SHAKE) + SCRIPTED_SPAWN 인텐트
- UX Continuity: 보스 처치 시 PERMANENT_REWARD 인텐트 발행
3. SpawnerSystem.ts (전면 재작성 v2.0)
- notifyScriptedSpawn(): Director로부터 스폰 요청 수신 (메서드 호출 방식)
- flushSpawnQueue(): 큐 소비 + MAX_ENEMIES_HARD_CAP(=30) 보호막
- activateSwarmBurst(): SWARM_BURST 모드 활성화
- tickSwarmBurst(): MAX_SWARM_BATCH(=6), SWARM_SPAWN_GAP(=3프레임) 분산 스태거링
- 절차적 스폰: difficultyMult 기반 간격 계산, 타임라인 간격 채우기 보조 역할
- dispose(): 큐 + 버스트 상태 초기화
4. EngineProtocol.ts (확장)
- SCRIPTED_SPAWN, SPAWN_MODE, EXP_DENSITY_BOOST, PERMANENT_REWARD 인텐트 타입 추가
🧠 사용한 지식 (Knowledge Used)
- Time-Based Difficulty Scaling 패턴
- Object Pool + Staggered Spawn 패턴 (성능 최적화)
- "Death Trap Avoidance" 게임 디자인 원칙
- "UX Continuity" 실패 보상 설계
- TypeScript discriminated union (EngineIntentType)
- Observer → Direct Method Call 결정 (EventBus 미도입 상태에서의 최적 통신 방식)
✅ 결과 (Result)
TypeScript 에러 0개 — npx tsc --noEmit 클린 통과
🔗 연결 지식 (Relevant Knowledge)
- E:\Wiki\2nd\10_Wiki\Topics\Game-Design (Difficulty Curve, Spike Design, Time-Based Scaling)
- E:\Wiki\2nd\10_Wiki\Topics\Software-Architecture (Intent Protocol, Event-Driven)
- E:\Wiki\2nd\10_Wiki\Topics\Performance-Optimization (Staggered Spawn, Object Pooling)