docs: revise game enhancement spec after review
Fix critical issues from spec review: - Correct model.go line count (712, not 19K) and adjust Phase 1-1 scope - Acknowledge existing chat/freeze implementations, rescope accordingly - Add data model definitions (structs, BoltDB schemas) for all new entities - Move logging and config externalization to Phase 1 (foundation) - Align floor themes with boss patterns - Add testing strategy, data migration plan, and admin API contract Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,164 +13,341 @@ Catacombs 멀티플레이 로그라이크 던전 크롤러의 종합 고도화
|
|||||||
- 4 클래스(Warrior/Mage/Healer/Rogue), 8 몬스터 + 4 보스, 20층 던전
|
- 4 클래스(Warrior/Mage/Healer/Rogue), 8 몬스터 + 4 보스, 20층 던전
|
||||||
- 턴제 전투(5초 타임아웃), 상점, 업적 10개, 리더보드
|
- 턴제 전투(5초 타임아웃), 상점, 업적 10개, 리더보드
|
||||||
- BoltDB 영속화, SSH 핑거프린트 재접속
|
- BoltDB 영속화, SSH 핑거프린트 재접속
|
||||||
- `ui/model.go` ~19K 라인 (모든 화면 로직 집중)
|
- 인게임 채팅 구현됨 (`/` 키로 입력, `SendChat()` 브로드캐스트)
|
||||||
|
- 상태이상: 독, 화상, 빙결 이미 존재
|
||||||
|
- `ui/model.go` ~712라인 (라우팅/업데이트 디스패치), 화면별 `*_view.go`로 분리 완료
|
||||||
|
- 기존 협동 보너스: 2인 이상 같은 타겟 공격 시 +10% 대미지
|
||||||
|
|
||||||
## Phase 1: Foundation + Chat
|
## Phase 1: Foundation + Structured Logging
|
||||||
|
|
||||||
### 1-1. UI Refactoring
|
### 1-1. UI Architecture Refinement
|
||||||
|
|
||||||
**Problem:** `ui/model.go`가 ~19K 라인으로 모든 화면 상태를 단일 파일에서 관리. 새 기능 추가 시 버그 위험 증가, 유지보수 곤란.
|
**Problem:** `model.go` (712라인)의 `Update()` 메서드가 모든 화면의 키 입력을 하나의 switch문에서 처리. 새 화면/기능 추가 시 분기가 복잡해짐.
|
||||||
|
|
||||||
**Design:**
|
**Design:**
|
||||||
- 각 화면의 `Update`/`View` 로직을 해당 `*_view.go` 파일로 이동
|
|
||||||
- 각 화면을 독립적인 Bubble Tea `Model` 인터페이스로 추출 (`LobbyModel`, `GameModel`, `ShopModel` 등)
|
- 각 화면을 독립적인 Bubble Tea `Model` 인터페이스로 추출 (`LobbyModel`, `GameModel`, `ShopModel` 등)
|
||||||
- 메인 `Model`은 화면 간 라우팅만 담당하는 컨테이너 역할
|
- 각 `*_view.go`에 해당 화면의 `Update()`/`View()` 로직을 완전히 위임
|
||||||
|
- 메인 `Model`은 화면 전환 라우팅만 담당
|
||||||
- 공유 상태(게임 세션, DB, 뷰포트 크기 등)는 공통 `Context` 구조체로 추출
|
- 공유 상태(게임 세션, DB, 뷰포트 크기 등)는 공통 `Context` 구조체로 추출
|
||||||
|
|
||||||
**Success criteria:** `model.go` 500라인 이하의 라우터로 축소.
|
**Success criteria:** `model.go`의 `Update()` 메서드가 화면별 라우팅만 수행 (각 화면 로직 0라인).
|
||||||
|
|
||||||
### 1-2. In-game Chat
|
### 1-2. Chat Emote System
|
||||||
|
|
||||||
**Problem:** 멀티플레이에서 소통 수단이 없어 협동의 재미가 크게 떨어짐.
|
**Note:** 기본 채팅은 이미 구현됨 (`game/session.go:SendChat`, `/` 키 입력).
|
||||||
|
|
||||||
**Design:**
|
**Design:**
|
||||||
- `game/chat.go` — 채팅 메시지 브로드캐스트 (룸 내 플레이어 간)
|
- 이모트 프리셋 시스템 추가 (`/hi`, `/gg`, `/go`, `/wait`, `/help` 등)
|
||||||
- 게임 화면 하단에 채팅 로그 영역 추가
|
- 이모트는 채팅 로그에 강조 스타일로 표시
|
||||||
- `/` 키로 채팅 입력 모드 전환
|
- `game/emote.go` — 이모트 정의 및 파싱
|
||||||
- 이모트 프리셋 (`/hi`, `/gg` 등)
|
|
||||||
|
|
||||||
**Affected packages:** `game/`, `ui/`
|
### 1-3. Structured Logging
|
||||||
|
|
||||||
|
**Rationale:** Phase 2~3 디버깅을 위해 초기에 도입.
|
||||||
|
|
||||||
|
**Design:**
|
||||||
|
- `log/slog` (Go 표준) 도입, JSON 형식 구조화 로깅
|
||||||
|
- 이벤트: 접속, 게임 시작, 전투, 종료, 에러
|
||||||
|
- 패닉 리커버리 미들웨어 — 세션 크래시 격리
|
||||||
|
|
||||||
|
### 1-4. Configuration Externalization
|
||||||
|
|
||||||
|
**Rationale:** Phase 2~3에서 밸런스 상수를 추가하기 전에 설정 구조를 먼저 도입.
|
||||||
|
|
||||||
|
**Design:**
|
||||||
|
- `config/config.go` — YAML 파싱 및 기본값 관리
|
||||||
|
- `config.yaml` — 서버 포트, 턴 타임아웃, 몬스터 스케일링, 상점 가격 배율 등
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Config struct {
|
||||||
|
Server ServerConfig `yaml:"server"`
|
||||||
|
Game GameConfig `yaml:"game"`
|
||||||
|
Combat CombatConfig `yaml:"combat"`
|
||||||
|
Dungeon DungeonConfig `yaml:"dungeon"`
|
||||||
|
Backup BackupConfig `yaml:"backup"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GameConfig struct {
|
||||||
|
TurnTimeout time.Duration `yaml:"turn_timeout"` // default: 5s
|
||||||
|
MaxPlayers int `yaml:"max_players"` // default: 4
|
||||||
|
MaxFloors int `yaml:"max_floors"` // default: 20
|
||||||
|
CoopBonus float64 `yaml:"coop_bonus"` // default: 0.10
|
||||||
|
InventoryLimit int `yaml:"inventory_limit"` // default: 10
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Affected packages:** 전체 (상수 참조 부분), `server/`, `game/`
|
||||||
|
|
||||||
## Phase 2: Combat & Dungeon Enhancement
|
## Phase 2: Combat & Dungeon Enhancement
|
||||||
|
|
||||||
### 2-1. Combat System Expansion
|
### 2-1. Combat System Expansion
|
||||||
|
|
||||||
**Skill Tree:**
|
**Skill Tree:**
|
||||||
- 클래스별 3갈래 특성 트리 (예: Warrior → 탱커/버서커/전술가)
|
- 클래스별 2갈래 특성 트리 (MVP, 추후 3갈래 확장 가능)
|
||||||
- 층 클리어 시 포인트 획득, 런 내에서만 유효 (로그라이크 특성 유지)
|
- Warrior: 탱커 / 버서커
|
||||||
- `entity/skill_tree.go` — 트리 정의 및 포인트 적용 로직
|
- Mage: 원소술사 / 시간술사
|
||||||
|
- Healer: 수호자 / 사제
|
||||||
|
- Rogue: 암살자 / 약사
|
||||||
|
- 층 클리어 시 1포인트 획득, 브랜치당 3노드, 런 내에서만 유효
|
||||||
|
- 스킬 포인트 배분은 층 이동 화면에서 수행 (턴 동기화 불필요)
|
||||||
|
|
||||||
|
```go
|
||||||
|
// entity/skill_tree.go
|
||||||
|
type SkillBranch struct {
|
||||||
|
Name string
|
||||||
|
Nodes [3]SkillNode // 3 sequential unlocks per branch
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
type SkillNode struct {
|
||||||
|
Name string
|
||||||
|
Effect SkillEffect // enum: ATKBoost, DEFBoost, SkillPower, etc.
|
||||||
|
Value float64 // modifier amount
|
||||||
|
Required int // points spent in branch to unlock
|
||||||
|
}
|
||||||
|
|
||||||
|
type PlayerSkills struct {
|
||||||
|
BranchIndex int // 0 or 1 (chosen branch)
|
||||||
|
Points int // total points earned
|
||||||
|
Allocated int // points allocated in chosen branch
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
**Combo Skills:**
|
**Combo Skills:**
|
||||||
- 2인 이상이 같은 턴에 특정 조합 사용 시 연계 효과 발동
|
- 2인 이상이 같은 턴에 특정 조합 사용 시 연계 효과 발동
|
||||||
- 예: Mage 빙결 + Warrior 강타 = 빙쇄 대미지
|
- 기존 협동 보너스(+10%)와 별개로 스택됨
|
||||||
- `combat/combo.go` — 연계 조건 판정 및 효과 적용
|
- 예: Mage 빙결 + Warrior 강타 = 빙쇄 (대미지 1.5배 + 빙결 해제)
|
||||||
|
|
||||||
|
```go
|
||||||
|
// combat/combo.go
|
||||||
|
type ComboDefinition struct {
|
||||||
|
RequiredActions []ComboAction // class + action type pairs
|
||||||
|
Effect ComboEffect
|
||||||
|
Name string
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ComboAction struct {
|
||||||
|
Class entity.Class
|
||||||
|
ActionType string // "skill", "attack"
|
||||||
|
SkillName string // optional: specific skill required
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
**Elite Monsters:**
|
**Elite Monsters:**
|
||||||
- 일반 몬스터의 강화 변종, 특수 접두사 (맹독의/불타는/흡혈의 등)
|
- 일반 몬스터의 강화 변종, 층당 ~20% 확률로 등장
|
||||||
- 보스가 아닌 층에서 긴장감 추가
|
- 접두사별 스탯 변형 및 특수 능력
|
||||||
- `entity/elite.go` — 접두사 시스템 및 스탯 변형
|
|
||||||
|
```go
|
||||||
|
// entity/elite.go
|
||||||
|
type ElitePrefix struct {
|
||||||
|
Name string // "맹독의", "불타는", "흡혈의"
|
||||||
|
StatMod StatModifier // HP/ATK/DEF multipliers
|
||||||
|
OnHit StatusEffect // applied on monster's attack
|
||||||
|
DropBonus float64 // extra loot chance
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
**Status Effects Expansion:**
|
**Status Effects Expansion:**
|
||||||
- 기존: 독, 화상
|
- 기존: 독, 화상, 빙결
|
||||||
- 추가: 빙결(행동 불가), 출혈(턴마다 누적), 저주(회복량 감소)
|
- 추가: 출혈(턴마다 대미지 누적 +1), 저주(회복량 50% 감소)
|
||||||
- `entity/status.go` 확장
|
- `entity/player.go`에 `StatusBleed`, `StatusCurse` 추가
|
||||||
|
|
||||||
**Affected packages:** `entity/`, `combat/`, `game/`
|
**Success criteria:** 8개 스킬 브랜치, 5개 이상 콤보 조합, 5개 엘리트 접두사, 5개 상태이상.
|
||||||
|
|
||||||
### 2-2. Dungeon Event Diversification
|
### 2-2. Dungeon Event Diversification
|
||||||
|
|
||||||
**Random Event Rooms:**
|
**Random Event Rooms:**
|
||||||
- 선택지 기반 이벤트 (예: "수상한 제단 발견" → 제물 바치기/무시/파괴)
|
- 선택지 기반 이벤트 (예: "수상한 제단 발견" → 제물 바치기/무시/파괴)
|
||||||
- 각 선택지마다 다른 보상/페널티
|
- 최소 8개 이벤트 풀
|
||||||
- `game/random_event.go` — 이벤트 풀 및 결과 처리
|
|
||||||
|
```go
|
||||||
|
// game/random_event.go
|
||||||
|
type RandomEvent struct {
|
||||||
|
ID string
|
||||||
|
Description string
|
||||||
|
Choices []EventChoice
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventChoice struct {
|
||||||
|
Text string
|
||||||
|
Outcome EventOutcome // reward/penalty/mixed
|
||||||
|
Weight float64 // probability weight
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
**Secret Rooms:**
|
**Secret Rooms:**
|
||||||
- 낮은 확률(~10%)로 생성, 희귀 아이템/렐릭 보상
|
- 낮은 확률(~10%)로 생성, `dungeon/room.go`에 `RoomSecret` 타입 추가
|
||||||
- `dungeon/generator.go` 확장
|
- 희귀 아이템/렐릭 보상
|
||||||
|
|
||||||
**Floor Themes:**
|
**Floor Themes:**
|
||||||
- 5층 단위로 환경 효과
|
- 5층 단위로 환경 효과, 보스 패턴과 테마 정렬:
|
||||||
- 1~5층 습지: 독 대미지 증가
|
- 1~5층 습지 (독 강화) → Guardian 보스 (독 패턴으로 변경)
|
||||||
- 6~10층 화산: 화상 대미지 증가
|
- 6~10층 화산 (화상 강화) → Warden 보스 (화상 패턴으로 변경)
|
||||||
- 11~15층 얼음: 빙결 확률 증가
|
- 11~15층 얼음 (빙결 강화) → Overlord 보스 (빙결 패턴)
|
||||||
- 16~20층 지옥: 모든 상태이상 강화
|
- 16~20층 지옥 (전체 강화) → Archfiend 최종 보스
|
||||||
- `dungeon/theme.go` — 테마별 환경 효과 정의
|
|
||||||
|
```go
|
||||||
|
// dungeon/theme.go
|
||||||
|
type FloorTheme struct {
|
||||||
|
Name string
|
||||||
|
StatusBoost entity.StatusEffect // which status is empowered
|
||||||
|
DamageModifier float64 // multiplier for boosted status
|
||||||
|
AsciiStyle string // visual theme for rendering
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
**Mini-boss Rooms:**
|
**Mini-boss Rooms:**
|
||||||
- 보스 층 직전(4, 9, 14, 19층)에 미니보스 등장
|
- 보스 층 직전(4, 9, 14, 19층)에 미니보스 등장
|
||||||
- 보스 전 준비 테스트 역할
|
- 기존 `Monster` 구조체에 `IsMiniBoss bool` 추가, `BossPattern` 사용하되 HP/ATK는 보스의 60%
|
||||||
|
|
||||||
**Affected packages:** `dungeon/`, `game/`, `entity/`
|
**Prerequisite for Phase 3-1:** 던전 생성을 시드 기반으로 리팩토링.
|
||||||
|
- `GenerateFloor(floor int)` → `GenerateFloor(floor int, rng *rand.Rand)`
|
||||||
|
- 모든 랜덤 호출을 `rng` 인스턴스로 교체
|
||||||
|
|
||||||
|
**Success criteria:** 8개 이상 랜덤 이벤트, 4개 층 테마, 비밀 방, 4개 미니보스.
|
||||||
|
|
||||||
|
**Affected packages:** `dungeon/`, `game/`, `entity/`, `combat/`
|
||||||
|
|
||||||
## Phase 3: Retention Systems
|
## Phase 3: Retention Systems
|
||||||
|
|
||||||
### 3-1. Daily Challenge
|
### 3-1. Daily Challenge
|
||||||
|
|
||||||
- 날짜 기반 시드로 동일한 던전 구조/몬스터 배치 생성
|
- 날짜 기반 시드(`time.Now().Format("2006-01-02")` → hash → seed)로 동일 던전 생성
|
||||||
|
- Phase 2-2에서 리팩토링된 시드 기반 생성기 활용
|
||||||
- 일일 전용 리더보드
|
- 일일 전용 리더보드
|
||||||
- 참여 시 포인트 적립, 연속 참여 보너스
|
|
||||||
- `game/daily.go` — 시드 생성 및 일일 세션 관리
|
```go
|
||||||
- `store/daily.go` — 일일 기록 및 연속 참여 추적
|
// store/daily.go (BoltDB bucket: "daily_runs")
|
||||||
|
// Key: "YYYY-MM-DD:playerFingerprint"
|
||||||
|
type DailyRecord struct {
|
||||||
|
Date string `json:"date"`
|
||||||
|
Player string `json:"player"`
|
||||||
|
FloorReached int `json:"floor_reached"`
|
||||||
|
GoldEarned int `json:"gold_earned"`
|
||||||
|
Streak int `json:"streak"` // consecutive days played
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Success criteria:** 동일 날짜에 같은 시드 던전 보장, 일일 리더보드 표시.
|
||||||
|
|
||||||
### 3-2. Meta Progression
|
### 3-2. Meta Progression
|
||||||
|
|
||||||
**Unlock System Expansion:**
|
**Unlock System:**
|
||||||
- 현재 업적 10개 → 조건부 언락 콘텐츠 추가
|
|
||||||
- "10층 이상 클리어" → 5번째 클래스 해금
|
```go
|
||||||
- "3인 이상 클리어" → 하드 모드 해금
|
// store/unlocks.go (BoltDB bucket: "unlocks")
|
||||||
- `store/unlocks.go` — 언락 조건 및 상태 관리
|
// Key: "playerFingerprint:unlockID"
|
||||||
|
type Unlock struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Condition string `json:"condition"` // human-readable
|
||||||
|
Unlocked bool `json:"unlocked"`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
언락 콘텐츠:
|
||||||
|
- "10층 이상 클리어" → 5번째 클래스 해금
|
||||||
|
- "3인 이상 클리어" → 하드 모드 해금
|
||||||
|
- "20층 클리어" → 주간 변이 모드 해금
|
||||||
|
|
||||||
**Player Titles:**
|
**Player Titles:**
|
||||||
- 업적/기록 기반 칭호 부여
|
|
||||||
- 로비에서 닉네임 옆에 표시
|
```go
|
||||||
- `store/titles.go` — 칭호 정의 및 부여 로직
|
// store/titles.go (BoltDB bucket: "titles")
|
||||||
|
// Key: "playerFingerprint"
|
||||||
|
type PlayerTitle struct {
|
||||||
|
ActiveTitle string `json:"active_title"`
|
||||||
|
Earned []string `json:"earned"` // list of title IDs
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
**Codex System:**
|
**Codex System:**
|
||||||
- 조우한 몬스터/획득한 아이템/발견한 이벤트 기록
|
|
||||||
- 도감 완성률 표시
|
```go
|
||||||
- `store/codex.go` — 도감 데이터 관리
|
// store/codex.go (BoltDB bucket: "codex")
|
||||||
- `ui/codex_view.go` — 도감 화면
|
// Key: "playerFingerprint"
|
||||||
|
type Codex struct {
|
||||||
|
Monsters map[string]bool `json:"monsters"` // monsterID → encountered
|
||||||
|
Items map[string]bool `json:"items"` // itemID → acquired
|
||||||
|
Events map[string]bool `json:"events"` // eventID → discovered
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `ui/codex_view.go` — 도감 화면, 완성률 표시
|
||||||
|
|
||||||
|
**Success criteria:** 3개 이상 언락 콘텐츠, 5개 이상 칭호, 도감 완성률 추적.
|
||||||
|
|
||||||
### 3-3. Difficulty System
|
### 3-3. Difficulty System
|
||||||
|
|
||||||
**Hard Mode:**
|
**Hard Mode:**
|
||||||
|
- 난이도 배율은 `config.yaml`에서 관리 (Phase 1-4의 설정 구조 활용)
|
||||||
- 몬스터 스탯 1.5배, 상점 가격 2배, 회복량 절반
|
- 몬스터 스탯 1.5배, 상점 가격 2배, 회복량 절반
|
||||||
- 언락 조건 충족 시 선택 가능
|
- 언락 조건 충족 시 로비에서 선택 가능
|
||||||
|
|
||||||
**Weekly Mutations:**
|
**Weekly Mutations:**
|
||||||
- 매주 바뀌는 특수 규칙
|
- 매주 바뀌는 특수 규칙, 주 번호 기반 시드로 결정
|
||||||
- "스킬 사용 불가", "엘리트만 등장", "상점 없음" 등
|
|
||||||
- `game/mutation.go` — 주간 변이 규칙 정의 및 적용
|
|
||||||
|
|
||||||
**Affected packages:** `game/`, `store/`, `ui/`
|
```go
|
||||||
|
// game/mutation.go
|
||||||
|
type Mutation struct {
|
||||||
|
ID string
|
||||||
|
Name string // "스킬 봉인", "엘리트 범람", "상점 폐쇄" 등
|
||||||
|
Description string
|
||||||
|
Apply func(cfg *config.GameConfig) // config 값 오버라이드
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Affected packages:** `game/`, `store/`, `ui/`, `config/`
|
||||||
|
|
||||||
## Phase 4: Operational Stability
|
## Phase 4: Operational Stability
|
||||||
|
|
||||||
### 4-1. Logging & Monitoring
|
### 4-1. Admin Dashboard
|
||||||
|
|
||||||
- `log/slog` (Go 표준) 도입, JSON 형식 구조화 로깅
|
- `/admin` HTTP 엔드포인트 (Basic Auth 인증)
|
||||||
- 이벤트: 접속, 게임 시작, 전투, 종료, 에러
|
- JSON 응답 형식:
|
||||||
- `/admin` HTTP 엔드포인트 — 접속자 수, 활성 방, 오늘의 런 수, 평균 클리어 층수
|
|
||||||
- 패닉 리커버리 미들웨어 — 세션 크래시 격리
|
|
||||||
|
|
||||||
**Affected packages:** `server/`, `web/`, `game/`
|
```go
|
||||||
|
type AdminStats struct {
|
||||||
|
OnlinePlayers int `json:"online_players"`
|
||||||
|
ActiveRooms int `json:"active_rooms"`
|
||||||
|
TodayRuns int `json:"today_runs"`
|
||||||
|
AvgFloorReach float64 `json:"avg_floor_reached"`
|
||||||
|
Uptime time.Duration `json:"uptime"`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### 4-2. Data Safety
|
### 4-2. Data Safety
|
||||||
|
|
||||||
- 설정 가능한 주기로 DB 파일 자동 백업 (`./data/backup/`)
|
- 설정 가능한 주기로 DB 파일 자동 백업 (`./data/backup/`, `config.yaml`의 `backup.interval`)
|
||||||
- 그레이스풀 셧다운: SIGTERM 시 진행 중인 세션 저장 후 종료
|
- 그레이스풀 셧다운: SIGTERM 시 진행 중인 세션 저장 후 종료
|
||||||
- 재시작 시 미완료 세션 정리
|
- 재시작 시 미완료 세션 정리
|
||||||
|
|
||||||
**Affected packages:** `store/`, `main.go`
|
**Affected packages:** `store/`, `web/`, `main.go`
|
||||||
|
|
||||||
### 4-3. Configuration Externalization
|
## Data Migration
|
||||||
|
|
||||||
- `config.yaml` — 서버 포트, 턴 타임아웃, 몬스터 스케일링, 상점 가격 배율 등
|
기존 BoltDB 데이터와의 호환성:
|
||||||
- 밸런스 조정 시 재빌드 없이 설정 파일만 수정
|
- 새 버킷(`daily_runs`, `unlocks`, `titles`, `codex`)은 `CreateBucketIfNotExists`로 안전하게 추가
|
||||||
- `config/config.go` — YAML 파싱 및 기본값 관리
|
- 기존 `profiles`, `rankings`, `achievements` 버킷은 구조 변경 없음
|
||||||
|
- 업적 시스템과 언락 시스템은 별도 버킷으로 독립 운영 (기존 업적 데이터 보존)
|
||||||
|
|
||||||
**Affected packages:** 전체 (상수 참조 부분)
|
## Testing Strategy
|
||||||
|
|
||||||
|
- **단위 테스트:** 새 패키지별 `*_test.go` (스킬 트리 포인트 계산, 콤보 판정, 엘리트 스탯 변형)
|
||||||
|
- **시드 결정성 테스트:** 동일 시드 → 동일 던전 보장 검증
|
||||||
|
- **밸런스 시뮬레이션:** 엘리트/미니보스 스탯 범위가 솔로/파티 모두에서 적정한지 수치 검증
|
||||||
|
- **통합 테스트:** 턴 실행 시 콤보 판정 → 대미지 계산 → 상태이상 적용 흐름
|
||||||
|
|
||||||
## Dependencies Between Phases
|
## Dependencies Between Phases
|
||||||
|
|
||||||
```
|
```
|
||||||
Phase 1 (Foundation)
|
Phase 1 (Foundation: UI정리 + 로깅 + 설정 외부화)
|
||||||
└── Phase 2 (Combat/Dungeon) — UI 리팩토링 완료 후 새 화면 추가가 용이
|
├── Phase 2 (Combat/Dungeon) — 설정 구조 위에 밸런스 상수 추가
|
||||||
└── Phase 3 (Retention) — 전투/던전 콘텐츠 위에 메타 시스템 구축
|
│ └── Phase 3 (Retention) — 시드 기반 생성기, 콘텐츠 위에 메타 시스템
|
||||||
└── Phase 4 (Operations) — 전체 기능 완성 후 운영 도구 보강
|
└── Phase 4 (Operations) — 로깅 기반 위에 어드민/백업 추가
|
||||||
```
|
```
|
||||||
|
|
||||||
Phase 4의 로깅/설정 외부화는 독립적이므로, 필요 시 Phase 2~3과 병행 가능.
|
Phase 4는 Phase 1 완료 후 독립 진행 가능 (Phase 2~3과 병행).
|
||||||
|
|
||||||
## Out of Scope
|
## Out of Scope
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user