- Archfiend → Archlich (matches codebase) - Clarify AoE pattern moves from Guardian to Archlich final boss Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
12 KiB
Catacombs Game Enhancement Design
Overview
Catacombs 멀티플레이 로그라이크 던전 크롤러의 종합 고도화 설계. 실제 유저 운영(소규모 10~30명 커뮤니티) 목표로, 재미/리텐션/안정성 중심.
접근 방식: 기반 정비 → 콘텐츠 → 리텐션 → 운영 (접근 A)
Current State
- Go + Bubble Tea TUI, SSH(:2222) + WebSocket(:8080) 듀얼 접속
- 4 클래스(Warrior/Mage/Healer/Rogue), 8 몬스터 + 4 보스, 20층 던전
- 턴제 전투(5초 타임아웃), 상점, 업적 10개, 리더보드
- BoltDB 영속화, SSH 핑거프린트 재접속
- 인게임 채팅 구현됨 (
/키로 입력,SendChat()브로드캐스트) - 상태이상: 독, 화상, 빙결 이미 존재
ui/model.go~712라인 (라우팅/업데이트 디스패치), 화면별*_view.go로 분리 완료- 기존 협동 보너스: 2인 이상 같은 타겟 공격 시 +10% 대미지
Phase 1: Foundation + Structured Logging
1-1. UI Architecture Refinement
Problem: model.go (712라인)의 Update() 메서드가 모든 화면의 키 입력을 하나의 switch문에서 처리. 새 화면/기능 추가 시 분기가 복잡해짐.
Design:
- 각 화면을 독립적인 Bubble Tea
Model인터페이스로 추출 (LobbyModel,GameModel,ShopModel등) - 각
*_view.go에 해당 화면의Update()/View()로직을 완전히 위임 - 메인
Model은 화면 전환 라우팅만 담당 - 공유 상태(게임 세션, DB, 뷰포트 크기 등)는 공통
Context구조체로 추출
Success criteria: model.go의 Update() 메서드가 화면별 라우팅만 수행 (각 화면 로직 0라인).
1-2. Chat Emote System
Note: 기본 채팅은 이미 구현됨 (game/session.go:SendChat, / 키 입력).
Design:
- 이모트 프리셋 시스템 추가 (
/hi,/gg,/go,/wait,/help등) - 이모트는 채팅 로그에 강조 스타일로 표시
game/emote.go— 이모트 정의 및 파싱
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— 서버 포트, 턴 타임아웃, 몬스터 스케일링, 상점 가격 배율 등
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
2-1. Combat System Expansion
Skill Tree:
- 클래스별 2갈래 특성 트리 (MVP, 추후 3갈래 확장 가능)
- Warrior: 탱커 / 버서커
- Mage: 원소술사 / 시간술사
- Healer: 수호자 / 사제
- Rogue: 암살자 / 약사
- 층 클리어 시 1포인트 획득, 브랜치당 3노드, 런 내에서만 유효
- 스킬 포인트 배분은 층 이동 화면에서 수행 (턴 동기화 불필요)
// 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:
- 2인 이상이 같은 턴에 특정 조합 사용 시 연계 효과 발동
- 기존 협동 보너스(+10%)와 별개로 스택됨
- 예: Mage 빙결 + Warrior 강타 = 빙쇄 (대미지 1.5배 + 빙결 해제)
// 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:
- 일반 몬스터의 강화 변종, 층당 ~20% 확률로 등장
- 접두사별 스탯 변형 및 특수 능력
// 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:
- 기존: 독, 화상, 빙결
- 추가: 출혈(턴마다 대미지 누적 +1), 저주(회복량 50% 감소)
entity/player.go에StatusBleed,StatusCurse추가
Success criteria: 8개 스킬 브랜치, 5개 이상 콤보 조합, 5개 엘리트 접두사, 5개 상태이상.
2-2. Dungeon Event Diversification
Random Event Rooms:
- 선택지 기반 이벤트 (예: "수상한 제단 발견" → 제물 바치기/무시/파괴)
- 최소 8개 이벤트 풀
// 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:
- 낮은 확률(~10%)로 생성,
dungeon/room.go에RoomSecret타입 추가 - 희귀 아이템/렐릭 보상
Floor Themes:
- 5층 단위로 환경 효과, 보스 패턴과 테마 정렬:
- 1~5층 습지 (독 강화) → Guardian 보스 (독 패턴으로 변경)
- 6~10층 화산 (화상 강화) → Warden 보스 (화상 패턴으로 변경)
- 11~15층 얼음 (빙결 강화) → Overlord 보스 (빙결 패턴)
- 16~20층 지옥 (전체 강화) → Archlich 최종 보스 (AoE + 회복 패턴, 기존 Guardian의 AoE를 최종 보스로 이동)
// 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:
- 보스 층 직전(4, 9, 14, 19층)에 미니보스 등장
- 기존
Monster구조체에IsMiniBoss bool추가,BossPattern사용하되 HP/ATK는 보스의 60%
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
3-1. Daily Challenge
- 날짜 기반 시드(
time.Now().Format("2006-01-02")→ hash → seed)로 동일 던전 생성 - Phase 2-2에서 리팩토링된 시드 기반 생성기 활용
- 일일 전용 리더보드
// 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
Unlock System:
// store/unlocks.go (BoltDB bucket: "unlocks")
// 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:
// 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:
// store/codex.go (BoltDB bucket: "codex")
// 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
Hard Mode:
- 난이도 배율은
config.yaml에서 관리 (Phase 1-4의 설정 구조 활용) - 몬스터 스탯 1.5배, 상점 가격 2배, 회복량 절반
- 언락 조건 충족 시 로비에서 선택 가능
Weekly Mutations:
- 매주 바뀌는 특수 규칙, 주 번호 기반 시드로 결정
// 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
4-1. Admin Dashboard
/adminHTTP 엔드포인트 (Basic Auth 인증)- JSON 응답 형식:
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
- 설정 가능한 주기로 DB 파일 자동 백업 (
./data/backup/,config.yaml의backup.interval) - 그레이스풀 셧다운: SIGTERM 시 진행 중인 세션 저장 후 종료
- 재시작 시 미완료 세션 정리
Affected packages: store/, web/, main.go
Data Migration
기존 BoltDB 데이터와의 호환성:
- 새 버킷(
daily_runs,unlocks,titles,codex)은CreateBucketIfNotExists로 안전하게 추가 - 기존
profiles,rankings,achievements버킷은 구조 변경 없음 - 업적 시스템과 언락 시스템은 별도 버킷으로 독립 운영 (기존 업적 데이터 보존)
Testing Strategy
- 단위 테스트: 새 패키지별
*_test.go(스킬 트리 포인트 계산, 콤보 판정, 엘리트 스탯 변형) - 시드 결정성 테스트: 동일 시드 → 동일 던전 보장 검증
- 밸런스 시뮬레이션: 엘리트/미니보스 스탯 범위가 솔로/파티 모두에서 적정한지 수치 검증
- 통합 테스트: 턴 실행 시 콤보 판정 → 대미지 계산 → 상태이상 적용 흐름
Dependencies Between Phases
Phase 1 (Foundation: UI정리 + 로깅 + 설정 외부화)
├── Phase 2 (Combat/Dungeon) — 설정 구조 위에 밸런스 상수 추가
│ └── Phase 3 (Retention) — 시드 기반 생성기, 콘텐츠 위에 메타 시스템
└── Phase 4 (Operations) — 로깅 기반 위에 어드민/백업 추가
Phase 4는 Phase 1 완료 후 독립 진행 가능 (Phase 2~3과 병행).
Out of Scope
- 대규모(100+) 스케일링 (분산 서버, 로드밸런싱)
- 모바일/데스크톱 네이티브 클라이언트
- 유료 결제/과금 시스템
- PvP 대전 모드
- 외부 DB 마이그레이션 (BoltDB 유지)