Files
Catacombs/docs/superpowers/specs/2026-03-23-catacombs-design.md
tolelom 8f1a00d8c5 Update design spec with review feedback
Add multiplayer state sync model, concrete stats, movement model,
monster AI, lobby/disconnect handling, economy, and chat system.
Fix room probabilities, combat action naming, and AoE interactions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 23:15:59 +09:00

280 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Catacombs — Design Spec
SSH 멀티플레이어 협동 로그라이크 터미널 게임
## Overview
Go + Charm 스택 기반의 SSH 접속 멀티플레이어 협동 로그라이크. 2~4인 파티가 절차적 생성 던전을 탐험하며, 반실시간 턴제 전투와 클래스 기반 역할 분담으로 20층 던전을 클리어하는 게임.
- **접속:** SSH 메인 (`ssh catacombs.tolelom.xyz`), 웹 터미널 추후 추가
- **한 판:** 30~45분, 고정 20층
- **인원:** 2~4인 협동
- **시각:** 박스 드로잉 + ANSI 컬러
## Architecture
단일 Go 바이너리 모놀리스, Docker 컨테이너 하나로 배포.
```
┌─────────────────────────────────────────┐
│ Docker Container │
│ │
│ ┌─────────────┐ ┌────────────────┐ │
│ │ Wish SSH │──▶│ Bubble Tea │ │
│ │ Server │ │ TUI Engine │ │
│ │ :2222 │ └───────┬────────┘ │
│ └─────────────┘ │ │
│ ┌───────▼────────┐ │
│ │ Game Engine │ │
│ │ - Lobby │ │
│ │ - Dungeon │ │
│ │ - Combat │ │
│ │ - Turn Timer │ │
│ └───────┬────────┘ │
│ ┌───────▼────────┐ │
│ │ BoltDB │ │
│ │ (랭킹, 통계) │ │
│ └────────────────┘ │
└─────────────────────────────────────────┘
```
### Dependencies
- `charmbracelet/wish` — SSH 서버
- `charmbracelet/bubbletea` — TUI 프레임워크
- `charmbracelet/lipgloss` — 스타일링 (색상, 박스 드로잉)
- `go.etcd.io/bbolt` — 경량 임베디드 DB (랭킹/통계)
### Multiplayer State Sync
각 게임 세션(파티)마다 하나의 `GameSession` goroutine이 중앙 게임 루프를 돌린다.
```
┌──────────────┐
Player A (SSH) ──▶ │ │ ──▶ tea.Msg to A
Player B (SSH) ──▶ │ GameSession │ ──▶ tea.Msg to B
Player C (SSH) ──▶ │ goroutine │ ──▶ tea.Msg to C
└──────────────┘
```
- 각 플레이어의 Bubble Tea 프로그램은 입력을 `GameSession`의 채널로 전송
- `GameSession`은 턴 타이머 관리, 입력 수집, 게임 상태 갱신을 담당
- 상태 갱신 후 각 플레이어의 `tea.Program.Send()``StateUpdateMsg` 브로드캐스트
- 게임 상태는 `GameSession`이 단독 소유 (lock-free, 채널 기반)
- 플레이어의 TUI 모델은 수신한 `StateUpdateMsg`를 렌더링만 함 (읽기 전용 뷰)
### Deployment
- Docker 이미지 빌드, Mac Mini에서 `docker compose up`
- SSH 포트(2222)는 Docker에서 직접 호스트 포트로 노출 (Caddy 불필요 — SSH는 TCP라 L7 프록시 대상 아님)
- `ssh -p 2222 tolelom.xyz`
- 플레이어 식별: SSH 공개키 fingerprint 기반. 최초 접속 시 닉네임 설정, BoltDB에 저장
## Game Flow
```
SSH 접속 → 타이틀 → 로비 (방 생성/참가) → 클래스 선택 → 던전 탐험
→ 이벤트 (전투/상점/보물) → 다음 층 or 사망 → 결과 화면 → 랭킹
```
### Movement Model
- **파티 단위 이동**: 파티는 하나의 유닛으로 방-to-방(room-to-room) 이동
- 탐험 중에는 자유 이동 (턴 타이머 없음), 아무 파티원이 방향 선택 가능
- 전투방 진입 시 자동으로 턴 모드 전환
- 전투 중 이동은 턴 액션 소모 (이동 OR 공격, 둘 다는 불가)
- 전투 중 이동은 도주 판정 (50% 확률 성공, 실패 시 턴 낭비)
### Turn System (반실시간)
전투 중에만 활성화. 탐험 중에는 자유 이동.
1. 서버가 "행동 입력 대기" 상태 시작, 5초 타이머
2. 각 플레이어가 공격/스킬/아이템/도주/대기 중 선택
3. 타이머 종료 시 미입력 플레이어는 대기(방어 자세)
4. 모든 입력 수집 → 동시 실행 → 결과 렌더링
5. 적 턴 자동 실행 → 다음 턴
## Classes
| 클래스 | HP | ATK | DEF | 역할 | 특수 스킬 |
|--------|-----|-----|-----|------|-----------|
| 전사 | 120 | 12 | 8 | 탱커 | 도발 (적 어그로 2턴 집중) |
| 마법사 | 70 | 20 | 3 | 딜러 | 화염구 (전체 적 0.8x 데미지) |
| 힐러 | 90 | 8 | 5 | 서포터 | 치유 (아군 1명 HP 30 회복) |
| 도적 | 85 | 15 | 4 | 유틸 | 정찰 (다음 방 미리보기) |
## Combat System
- 파티 vs 몬스터 그룹 (1~5마리)
- 행동 선택: `[공격] [스킬] [아이템] [도주] [대기]`
- 타겟 지정: 방향키/번호로 적 선택
- 데미지 계산: `max(1, ATK × 스킬배율 - DEF) × 랜덤(0.85~1.15)`
- 협동 보너스: 같은 적을 2명 이상 단일 대상 공격 시, 2번째 이후 공격자에게 10% 추가 데미지 (DEF 감산 후 적용). AoE 스킬은 협동 보너스 트리거/대상에서 제외
### Monster Stats (기준)
| 몬스터 | HP | ATK | DEF | 등장 층 |
|--------|-----|-----|-----|---------|
| 슬라임 | 20 | 5 | 1 | 1~5 |
| 스켈레톤 | 35 | 10 | 4 | 3~10 |
| 오크 | 55 | 14 | 6 | 6~14 |
| 다크나이트 | 80 | 18 | 10 | 12~20 |
| 보스 (5층) | 150 | 15 | 8 | 5 |
| 보스 (10층) | 250 | 22 | 12 | 10 |
| 보스 (15층) | 400 | 30 | 16 | 15 |
| 최종 보스 | 600 | 40 | 20 | 20 |
일반 몬스터는 층마다 HP/ATK +15% 스케일링 (기준값 × 1.15^(현재층-등장시작층)).
### Monster AI
- 기본: 가장 가까운 플레이어 공격
- 도발 상태의 전사가 있으면 전사에게 집중 (2턴)
- HP 가장 낮은 아군이 있으면 30% 확률로 타겟 변경
- 보스: 매 3턴마다 전체 공격 (0.5x 데미지). 도발은 단일 대상 공격만 유도, AoE는 도발 무시
### Economy
| 항목 | 가격 |
|------|------|
| 몬스터 처치 골드 | 5~15 (층에 비례) |
| 소모품 (HP 포션) | 20 |
| 무기 (ATK+3~8) | 40~80 |
| 방어구 (DEF+2~5) | 30~60 |
| 유물 | 100~150 |
### Progression
- 레벨업 없음 (로그라이크)
- 성장은 아이템 의존 — 무기, 방어구, 소모품, 특수 유물
- 층마다 상점 등장 확률 30%, 골드로 아이템 구매
- 유물은 패시브 효과 (예: "적 처치 시 HP 5 회복")
## Dungeon Generation
- BSP(Binary Space Partitioning)로 층마다 맵 생성
- 한 층: 5~8개 방 + 복도로 연결
- 맵 크기: 약 60×30 타일
### Room Types
| 타입 | 확률 | 내용 |
|------|------|------|
| 일반 전투 | 45% | 몬스터 조우 |
| 보물방 | 15% | 아이템 획득 |
| 상점 | 10% | 골드로 아이템 구매 |
| 이벤트 | 15% | 랜덤 이벤트 (함정, 축복 등) |
| 빈 방 | 15% | 안전지대 |
보스방은 확률과 별개로 매 층 1개 고정 배치. 나머지 4~7개 방에 위 확률 적용.
### Field of View
- 전장의 안개(Fog of War) — 파티 주변만 보임
- 도적의 정찰 스킬로 시야 확장 가능
- 방문한 방은 희미하게 표시
## Rendering
```
┌─ Catacombs B3 ──────────── Party: 4/4 ─┐
│ │
│ ┌─────┐ ┌─────┐ │
│ │.....│───│..$..│ │
│ │..@..│ │.....│ ░░░░░ │
│ │..♦..│ └─────┘ ░░░░░ │
│ └──┬──┘ ░░░░░ │
│ │ │
│ ┌──┴──┐ ┌─────┐ │
│ │..D..│───│.....│ │
│ │.....│ │..?..│ │
│ └─────┘ └─────┘ │
│ │
├─────────────────────────────────────────┤
│ HP ██████░░ 65/100 │ 골드: 120 │
│ [1]이동 [2]공격 [3]스킬 [4]아이템 │
│ ⏱ 4.2s │
└─────────────────────────────────────────┘
```
`@` 플레이어 `♦` 아군 `D` 몬스터 `$` 아이템 `?` 이벤트 `░` 미탐사
최소 터미널 크기: 80×24. UI는 고정 너비 (80컬럼). 터미널이 작으면 접속 시 경고 표시.
## Difficulty & Balance
### Floor Scaling
- 몬스터 HP/ATK가 층마다 ~15% 증가
- 5층, 10층, 15층, 20층에 보스 등장
- 보스 처치 시 유물 확정 드랍
### Difficulty Curve
| 구간 | 층 | 특징 |
|------|-----|------|
| 초반 | 1~5 | 튜토리얼 느낌, 쉬운 적, 기본 아이템 수급 |
| 중반 | 6~12 | 역할 분담 중요해짐, 자원 관리 시작 |
| 후반 | 13~18 | 강적 등장, 유물 시너지로 승부 |
| 최종 | 19~20 | 최종 보스, 파티 연계 필수 |
### Death
- 개인 사망 → 해당 층에서는 관전 모드 (맵/채팅 가능, 행동 불가). 다음 층 시작 시 HP 30%로 부활
- 전멸 → 게임 오버, 결과 화면
- 세이브 없음 (로그라이크)
### Gold & Communication
- 골드는 개인 소유. 몬스터 처치 시 파티원 전원에게 동일 골드 지급
- 간이 채팅: 턴 입력 중 `/` 키로 한 줄 메시지 전송 (파티 전체에 표시)
### Disconnect Handling
- 접속 끊김 시 해당 플레이어는 자동 대기 모드 (매 턴 방어 자세)
- 60초 내 재접속 시 SSH 공개키로 식별하여 세션 복귀
- 60초 초과 시 파티에서 제거, 남은 인원으로 계속 진행
### Lobby
- 방 목록 표시 (방 이름, 현재 인원, 상태)
- 방 생성 시 4자리 코드 부여 (예: `ABCD`)
- 코드 입력으로 참가 또는 목록에서 선택
- 최소 1인으로 시작 가능. 솔로 시 몬스터 HP 50%로 감소 (의도적 하드모드는 아님)
- 동시 게임 세션 제한 없음 (서버 리소스 한도 내)
## Project Structure
```
catacombs/
├── main.go # 진입점, SSH 서버 시작
├── server/
│ └── ssh.go # Wish SSH 설정, 세션 관리
├── game/
│ ├── lobby.go # 로비, 방 생성/참가
│ ├── session.go # 게임 세션 (파티 상태 관리)
│ ├── turn.go # 턴 타이머, 입력 수집, 실행
│ └── event.go # 이벤트 처리 (전투, 상점, 보물 등)
├── dungeon/
│ ├── generator.go # BSP 던전 생성
│ ├── room.go # 방 타입, 내용물 배치
│ └── fov.go # 시야 계산
├── entity/
│ ├── player.go # 플레이어, 클래스, 인벤토리
│ ├── monster.go # 몬스터 정의, AI
│ └── item.go # 아이템, 유물
├── combat/
│ └── combat.go # 데미지 계산, 전투 로직
├── ui/
│ ├── model.go # Bubble Tea 메인 모델
│ ├── title.go # 타이틀 화면
│ ├── lobby_view.go # 로비 뷰
│ ├── game_view.go # 던전/전투 뷰
│ └── result_view.go # 결과 화면
├── store/
│ └── db.go # BoltDB 랭킹/통계
├── Dockerfile
└── docker-compose.yml
```