Files
Catacombs/docs/superpowers/specs/2026-03-25-game-enhancement-design.md
tolelom 7064544693 docs: fix boss naming and AoE pattern in spec
- 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>
2026-03-25 12:38:10 +09:00

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.goUpdate() 메서드가 화면별 라우팅만 수행 (각 화면 로직 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.goStatusBleed, 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.goRoomSecret 타입 추가
  • 희귀 아이템/렐릭 보상

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

  • /admin HTTP 엔드포인트 (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.yamlbackup.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 유지)