279 lines
16 KiB
Markdown
279 lines
16 KiB
Markdown
# Project SS — ROADMAP.md
|
||
> **용도:** AI 에이전트에게 `/goal Phase N 진행해줘` 명령 시 컨텍스트로 주입하는 개발 로드맵 문서.
|
||
> **규칙:** 각 Phase는 독립적으로 실행 가능하며, `완료 기준(Done Criteria)`을 모두 충족해야 다음 Phase로 진행한다.
|
||
|
||
---
|
||
|
||
## 개발 전략
|
||
|
||
**그레이박스 우선 전략 (Greybox First)**
|
||
|
||
이 프로젝트는 그래픽보다 게임플레이 검증을 먼저 완성하는 전략을 채택한다.
|
||
게임은 기획 단계에서 재미있어 보여도 실제 플레이 시 재미없는 경우가 많기 때문에,
|
||
시스템이 실제로 재미있는지를 먼저 확인하고, 그래픽은 마지막에 올린다.
|
||
|
||
```
|
||
[Phase 0~4] 그레이박스 구간 — 로직과 재미 검증이 목표. 비주얼은 최소한으로.
|
||
↓
|
||
[그레이박스 테스트] 외부 플레이어 피드백 수집 및 반복 수정
|
||
↓
|
||
[Phase 5] 검증된 게임 위에 비주얼 폴리싱 적용
|
||
↓
|
||
[출시]
|
||
```
|
||
|
||
**Phase 5는 Phase 0~4의 재미 검증이 완료된 후에만 진행한다.**
|
||
비주얼 작업을 먼저 시작하지 않는다.
|
||
|
||
---
|
||
|
||
## 현재 상태 (Current Status)
|
||
|
||
```
|
||
Phase 0 [x] 환경 세팅 & 아키텍처
|
||
Phase 1 [x] 코어 루프 프로토타입
|
||
Phase 2 [x] 자원 경제 & 덱빌딩
|
||
Phase 3 [x] 정치 시스템 & 스토리 페이징
|
||
Phase 4 [x] 멀티 엔딩 & 연대기
|
||
Phase 5 [ ] 비주얼 폴리싱 & UX ← 그레이박스 테스트 완료 후에만 착수
|
||
```
|
||
|
||
`[x]` 완료 · `[~]` 부분 완료(완료 기준 미충족 항목 있음) · `[ ]` 미착수
|
||
|
||
---
|
||
|
||
## ⚠️ 2026-07-09: 병렬 작업 브랜치 병합 (중요 — 반드시 읽을 것)
|
||
|
||
이 로컬 작업 폴더는 2026-06-24~25에 **다른 세션에서 origin/main에 푸시된 4개 커밋**을
|
||
받아오지 못한 채로 Phase 2~4 작업을 진행했다. 그 커밋들에는 이 로컬에서 독립적으로
|
||
다시 구현한 것과 겹치는 기능(파산 문책, 내러티브 태그, 오염 카드, 자산)이 서로 다른
|
||
방식으로 이미 존재했고, `git pull` 시점에 6개 파일에서 충돌이 나서 origin 쪽 구현을
|
||
기준으로 병합했다. 원인·과정·잔여 이슈는 아래 각 Phase 절의 "병합 참고" 박스에 정리했다.
|
||
|
||
**이 폴더가 유일한 작업 사본이 아니라면, 다음 세션을 시작하기 전에 반드시 `git fetch` +
|
||
`git log origin/main..HEAD` / `git log HEAD..origin/main`으로 분기 여부를 먼저 확인할 것.**
|
||
|
||
---
|
||
|
||
## 다음 단계
|
||
|
||
**Phase 0~4 그레이박스 작업이 모두 완료됐다.** 이제 외부 플레이어 그레이박스 테스트를 진행할 차례다.
|
||
Phase 5(비주얼 폴리싱)는 그 피드백을 반영한 뒤에만 착수한다.
|
||
|
||
```
|
||
/goal Phase 5 진행해줘 # 그레이박스 테스트 완료 후에만
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 0 — 프로젝트 환경 세팅 & 아키텍처 설계
|
||
|
||
**상태: `[x] 완료`**
|
||
|
||
**목표:** 본격적인 개발 전 코드 환경, 버전 관리, 데이터 파이프라인을 확립한다.
|
||
|
||
### 완료된 항목
|
||
- [x] VS Code + Claude Code 개발 환경
|
||
- [x] Gitea 리포지토리 + CI/CD 파이프라인
|
||
- [x] React 19 + Vite 8 프로젝트 (그레이박스 전략에 따라 선택)
|
||
- [x] CSV/JSON 데이터 파서 (papaparse 기반)
|
||
|
||
---
|
||
|
||
## Phase 1 — 코어 루프 프로토타입
|
||
|
||
**상태: `[x] 완료`**
|
||
|
||
**목표:** 스와이프 조작과 4대 파라미터 증감이 동작하는지 검증한다.
|
||
|
||
### 완료된 항목
|
||
- [x] 카드 스와이프 시스템 (좌/우/위)
|
||
- [x] 4대 핵심 파라미터 (내부 저항 / 엔트로피 / 대중 공황 / 위험 수용 계수)
|
||
- [x] 라운드 카운터 (결재 N건 → 의회 진입)
|
||
- [x] 파라미터 5단계 도달 시 게임 오버 분기
|
||
|
||
---
|
||
|
||
## Phase 2 — 자원 경제 & 로그라이크 덱빌딩
|
||
|
||
**상태: `[x] 완료`**
|
||
|
||
**목표:** 토큰 수급/소모, 덱 오염, 덱 압축(자산)의 전체 경제 루프를 완성한다.
|
||
|
||
### 완료된 항목
|
||
- [x] 토큰 시스템 (예산 / 인력 / 정보)
|
||
- [x] 영구 자원 태그 (재력 / 무력 / 감시)
|
||
- [x] 딜레마 카드 6종 분기 로직
|
||
- [x] 무제한 인벤토리 UI
|
||
- [x] 자산 기초 로직 (랜덤 획득)
|
||
- [x] 파이프라인 연쇄 반응 기초
|
||
- [x] **파산 문책 시스템** — 마이너스 결재 시 파산 카운터 증가(`GameScreen.jsx` `handleSwipe`), 의회에서 경고 배너 → 미개선 시 특별 청문회로 게임 오버(`CouncilScreen.jsx`)
|
||
- [x] **오염 카드 등급 확률** — 파라미터 단계(1~5)별 S/A/B/C 가중치 테이블로 의회 종료 시 오염 카드 주입(`GameScreen.jsx` `GRADE_WEIGHTS`, `injectContaminationCards`)
|
||
- [x] **자산 효과 4종** — 성질 변환 / 시한부 격리 / 물리적 영구 소각 / 결재권 강제 행사, 자산 슬롯 클릭으로 발동(`GameScreen.jsx` `activateAsset`)
|
||
|
||
### 완료 기준 (Done Criteria)
|
||
- [x] 토큰이 마이너스인 상태로 결재하면 파산 카운터가 증가한다.
|
||
- [x] 의회 단계에서 파산 카운터가 문책 로직에 실제로 반영된다.
|
||
- [x] 경고를 받은 뒤 다음 의회까지 마이너스를 회복하지 못하면 게임 오버된다.
|
||
- [x] 오염 카드 등급이 파라미터 단계에 비례하여 가중치대로 뽑힌다.
|
||
- [x] 자산 효과 4종이 각각 독립적으로 동작한다.
|
||
|
||
> **참고:** 오염 카드 콘텐츠(`cards.csv`의 신화/조직저항/사회공황/이사회압박 16종)는 등급별 1종씩만 채운 **초안**이다.
|
||
> 밸런스·문체 검토 후 디자이너가 등급별로 추가 카드를 늘리는 작업이 별도로 필요하다.
|
||
> 또한 A급 이상 신화 카드가 '뉴스 이벤트' 카드를 추가하는 연쇄 규칙(기획서 92-95행)은 이번 범위에 포함하지 않았다.
|
||
|
||
> **병합 참고 (2026-07-09):** origin/main에 미리 푸시되어 있던 다른 세션의 파산 문책 구현(정례회의
|
||
> 라운드가 늘수록 결재 건수가 8→6→4→2→0으로 줄어들고, 파산 카운터 5회 이상이면 의회에서 전 파라미터를
|
||
> 강제로 올리는 에스컬레이션 포함)이 더 완성도 높고 실제 사용자 피드백을 직접 반영한 것이었다. 그 버전을
|
||
> 기준으로 병합하면서 상태명을 `bankruptcyCounter/bankruptcyWarned` → `bankruptcyCount/bankruptcyWarning`으로
|
||
> 통일했다. 자산은 origin에 `assets.json`(이름 있는 개별 아이템 4종: 전임 국장의 만년필 등)이 준비돼 있었지만
|
||
> 실제 효과 로직이 연결돼 있지 않아서, 이 로컬에서 만든 "성질 변환/시한부 격리/물리적 영구 소각/결재권 강제
|
||
> 행사" 4종 기능 로직을 그대로 유지했다 — `assets.json`의 이름 있는 아이템 플레이버는 아직 미사용 상태다.
|
||
|
||
### 핵심 참조 문서
|
||
- `시스템 기획서` — 결재 단계, 덱 오염, 덱 압축, 자산 슬롯
|
||
- `PRD` — §3.2 결재 시스템, §3.3 자산 및 덱 압축 시스템
|
||
|
||
---
|
||
|
||
## Phase 3 — 정치 시스템 & 스토리 페이징 통합
|
||
|
||
**상태: `[x] 완료`**
|
||
|
||
**목표:** 그림자 위원회 투표와 내러티브 태그 기반 페이즈 전환을 완성한다.
|
||
|
||
### 완료된 항목
|
||
- [x] 그림자 위원회 13명 (상임 8 + 지부장 5 무작위)
|
||
- [x] 의회 투표 / 탄핵 / 법안 분기 기초
|
||
- [x] 국장 개입 액션 3종 (매수 / 장부 조작 / 내부 감사)
|
||
- [x] 내러티브 태그 기반 페이징 기초
|
||
- [x] 연대기(Chronicle) 팝업
|
||
- [x] **파벌 우호도 세부 조건** — 12개 글로벌 지부장 파벌이 각자 다른 공식으로 우호도를 계산한다(`GameScreen.jsx` `GLOBAL_FACTIONS`). 게임 시작 시 12개 중 5개를 무작위 선발(`factionRoster`), 매 의회마다 실시간 상태(토큰/태그/파라미터/자산/카운터)로 점수를 산출해 동맹/우호/중립/적대/파국 5단계 티어로 환산, 투표와 국장 개입 면역 여부를 결정한다(`CouncilScreen.jsx`).
|
||
- [x] **파산 카운터 → 의회 문책 연동** — Phase 2 작업으로 완료됨 (`CouncilScreen.jsx`가 `bankruptcyCounter`/`bankruptcyWarned`를 직접 참조)
|
||
- [x] **스토리 페이징 카드 풀 전환** — 초기 덱은 일상/위기만 포함되고, 고유 내러티브 태그 3종 도달 시 작전/극비 프로젝트 카드 풀이 실시간으로 덱에 개방된다(`GameScreen.jsx` `phase2Pool`/`phase2Unlocked`).
|
||
|
||
### 완료 기준 (Done Criteria)
|
||
- [x] 글로벌 지부장 12개 파벌의 우호도가 각자 다른 조건으로 개별 계산된다.
|
||
- [x] 파산 카운터가 의회 문책 로직에 연동된다.
|
||
- [x] 내러티브 태그 누적 시 등장 카드 풀이 실시간으로 전환된다.
|
||
|
||
> **참고 및 남은 과제:**
|
||
> - 상임 이사회 8명의 투표는 여전히 `params.risk` 기반 확률 처리다. 기획서상 이들은 국장의 '성향 태그'에 반응해야 하는데, 이 게임에는 아직 성향 태그 시스템 자체가 없어 범위 밖으로 남겨뒀다(§4.1 대응).
|
||
> - Playwright로 실제 브라우저에서 플레이 검증 중 **`params.risk >= 5`가 직접 게임오버를 발동시키지만 `EndingScreen`에 해당 분기가 없어 "미확인 종말" 폴백으로 빠지는 버그**를 발견해 수정했다(PRD상 risk는 탄핵 기준치일 뿐 직접 붕괴 조건이 아님).
|
||
|
||
> **병합 참고 (2026-07-09):** 내러티브 태그 시스템 자체를 origin 버전(재사용 가능한 태그 풀 방식, 아래 참고)으로
|
||
> 교체하면서 페이징 문턱도 "고유 태그 4개/8개" → "고유 태그 3개/6개"로 재조정했다(풀 크기 10종 기준).
|
||
|
||
### 핵심 참조 문서
|
||
- `스토리 바이블` — §4.2 글로벌 지부장 12개 파벌 상세
|
||
- `시스템 기획서` — 주간 의회 단계, 토큰 경제
|
||
- `유저플로우` — §3 주간 의회 단계 플로우
|
||
|
||
---
|
||
|
||
## Phase 4 — 멀티 엔딩 & 연대기 (콘텐츠 완성)
|
||
|
||
**상태: `[x] 완료`**
|
||
|
||
**목표:** 도감 수집이라는 게임의 최종 목표를 완성한다.
|
||
이 Phase 완료 후 그레이박스 테스트를 시작한다.
|
||
|
||
### 완료된 항목
|
||
- [x] **엔딩 판별기 (우선순위 순)** — `client/src/data/endings.js`의 `resolveEnding()`이 트리거(탄핵/붕괴)별로 아래 순서를 그대로 구현한다.
|
||
|
||
| 우선순위 | 엔딩 유형 | 트리거 조건 |
|
||
|---|---|---|
|
||
| 1 | 의회 정치 엔딩 | 탄핵 가결 + 의회 의장 성향 축(무력/재력/감시 중 게임 시작 시 무작위 선정) 태그 5 이상 |
|
||
| 2 | 내러티브 연쇄 엔딩 | 신화→조직저항→사회공황→이사회압박 오염 카드가 이 순서로 등장 |
|
||
| 3 | 변주된 붕괴 엔딩 | 기본 붕괴 조건 + 특정 자원 태그(3종)/토큰(3종) 보유 |
|
||
| 4 | 기본 붕괴 엔딩 | 파라미터 5단계 도달 or 탄핵 가결 (그 외 조건 미충족 시 폴백) |
|
||
|
||
- [x] **변주된 붕괴 엔딩** — 자원 태그 변주 3종(쿠데타/은폐된 멸망/자본의 폭주) + 토큰 변주 3종(야반도주/정보 암흑/긴축의 폭동)
|
||
- [x] **극단적 파라미터 조기 엔딩** — 단일 결재에서 위험 파라미터가 3단계 이상 급증하며 5단계에 도달하면 "돌이킬 수 없는 순간" 즉각 붕괴 엔딩 발동
|
||
- [x] **내러티브 연쇄 엔딩** — 오염 카드 4종을 지정 순서로 수집하면 해금, 이후 탄핵/붕괴 시 최우선 적용
|
||
- [x] **임기 만료 엔딩** (병합으로 추가) — 라운드가 거듭될수록 정례회의까지의 결재 건수가 8→6→4→2→0으로 줄어들다 0이 되면 발동
|
||
- [x] **도감 UI** — `EndingCodex.jsx` 신규 컴포넌트. 엔딩 화면에서 "📖 엔딩 도감 보기"로 열람, 해금 16종 중 몇 종 확인했는지 표시, 미해금은 "???"로 잠금 처리, `localStorage`(`ss_endings_v2`)에 엔딩 id 기준으로 영구 저장
|
||
- [x] **연대기 팝업 완성** — 턴별 타임라인 + 새로 획득한 내러티브 태그를 아이콘/설명과 함께 인라인으로 강조 표시, 상단에 수집한 태그 전체를 칩으로 요약(`ChroniclePopup.jsx/css`)
|
||
|
||
### 완료 기준 (Done Criteria)
|
||
- [x] 파라미터 5단계 도달 시 우선순위 판별기가 정확한 엔딩을 출력한다. (Playwright로 "군사 쿠데타" 변주 엔딩과 "정치적 탄핵" 기본 엔딩을 각각 실제로 트리거해 확인)
|
||
- [x] 엔딩 화면에 이름 / 서사 텍스트 / 원인 요약이 표시된다.
|
||
- [x] 해금 엔딩이 도감에 기록되고 재실행 후에도 유지된다. (localStorage 기반, id로 dedup)
|
||
- [x] 연대기 팝업에서 이번 회차 내러티브 히스토리를 확인할 수 있다.
|
||
|
||
> **참고:** 엔딩 도감 localStorage 키를 `ss_endings`(제목 문자열 기반, 취약)에서 `ss_endings_v2`(고유 id 기반)로 교체했다.
|
||
> 이전에 수동 플레이테스트로 쌓인 `ss_endings` 데이터는 새 키와 호환되지 않아 브라우저에서 도감이 0/16으로 보일 수 있다 —
|
||
> 프로토타입 단계라 마이그레이션 로직은 만들지 않았다.
|
||
|
||
> **병합 참고 (2026-07-09) — 내러티브 태그 시스템 최종본:** 이 Phase에서 한 번(카드당 자유 텍스트 키워드
|
||
> `left_narrative`/`right_narrative`) 재설계했었는데, 이후 origin/main에 병합할 다른 세션의 구현을 발견했다.
|
||
> 그 버전은 `narrative_tags.json`(재사용 가능한 태그 10종 — 아이콘+이름+설명, 예: "쿠데타의 그림자" 🗡️)과
|
||
> `cards.csv`의 `left_tag`/`right_tag` 컬럼(태그 id 참조) 조합으로, 처음 획득하는 태그일 때만 토스트 알림이
|
||
> 뜨고 진행도에 반영되는 방식이었다 — 사용자 피드백을 더 직접 반영한 더 성숙한 설계라 최종적으로 이 방식을
|
||
> 채택하고 자유 텍스트 방식은 폐기했다. 다만 origin의 `cards.csv`에는 태그 컬럼 자체가 비어 있어 실제로는
|
||
> 작동하지 않는 상태였으므로, `update_csv_tags.js`의 기존 11개 매핑을 참고해 새로 채워 넣고 태그 풀도
|
||
> 4종(쿠데타의 그림자/군중의 광기/정치적 압박/희생의 대가) 추가했다. 페이징 문턱도 "태그 풀 10종 중 고유
|
||
> 3종/6종 획득"으로 재조정했다.
|
||
|
||
> **이 Phase 완료 = 그레이박스 테스트 준비 완료.**
|
||
> Phase 5는 테스트 피드백 반영이 끝난 후 착수한다.
|
||
|
||
### 핵심 참조 문서
|
||
- `스토리 바이블` — §5 멀티 엔딩 매트릭스
|
||
- `유저플로우` — §4 엔딩 분기 및 도감 플로우
|
||
- `텍스트 와이어프레임` — §3.2 엔딩 결산 화면
|
||
|
||
---
|
||
|
||
## Phase 5 — 비주얼 폴리싱 & 다이제틱 UX
|
||
|
||
**상태: `[ ] 미착수`**
|
||
**착수 조건: 그레이박스 테스트 피드백 반영 완료 후에만 시작한다.**
|
||
|
||
**목표:** 재미가 검증된 게임 위에 몰입감 있는 시각·청각·촉각 피드백을 입힌다.
|
||
|
||
### 작업 항목
|
||
- [ ] **시각적 오염도 연출** — 오염 카드 테두리에 검은 얼룩·불탄 자국 CSS 효과
|
||
- [ ] **앰비언트 페이즈 비네팅**
|
||
- 페이즈 1: 없음 (`opacity 0.0`)
|
||
- 페이즈 2: 가장자리 어두운 테두리 (`opacity 0.4`)
|
||
- 페이즈 3: 붉게 점멸 (`opacity 0.8`)
|
||
- [ ] **스와이프 마찰력 피드백** — 오염도·위험 단계에 따라 카드 저항값 증가 (`0.8` → `1.5`)
|
||
- [ ] **햅틱 진동 4종**
|
||
|
||
| 종류 | 강도 | 지속 | 발동 조건 |
|
||
|---|---|---|---|
|
||
| `swipe-tick` | Light | 10ms | 일상 딜레마 스와이프 |
|
||
| `stamp-success` | Medium | 30ms | 자원 태그/자산 획득 |
|
||
| `crisis-hit` | Heavy | 50ms | 위기 강타 파라미터 상승 |
|
||
| `chain-reaction` | Light×3 | 10ms×3 | 파이프라인 연쇄 발동 |
|
||
|
||
- [ ] **오디오 앰비언트** — 페이즈 전환에 따른 배경 사운드 변화
|
||
- [ ] **파이프라인 연쇄 시각 이펙트** — 자산 아이콘 사이 발광 선 애니메이션
|
||
|
||
### 완료 기준 (Done Criteria)
|
||
- 페이즈 3 진입 시 화면 테두리가 붉게 점멸한다.
|
||
- 위기 강타 스와이프 시 Heavy 햅틱이 발동한다 (모바일 실기 확인).
|
||
- 파이프라인 연쇄 발동 시 발광 선 이펙트와 연속 진동이 함께 재생된다.
|
||
|
||
### 핵심 참조 문서
|
||
- `디자인 토큰` — §4 인터랙션 & 모션 토큰, §5 햅틱 피드백 토큰
|
||
- `컴포넌트 인벤토리` — `VFX_SimpleChain`, `Card_SwipeFull`
|
||
|
||
---
|
||
|
||
## 에이전트 사용법
|
||
|
||
```
|
||
# 감사 먼저 (현재 필수)
|
||
/goal 감사해줘 — Phase 2~3 미완 항목 실제 구현 여부 확인하고 보고해줘
|
||
|
||
# Phase 진행
|
||
/goal Phase 2 미완 항목 마무리해줘
|
||
/goal Phase 3 미완 항목 마무리해줘
|
||
/goal Phase 4 진행해줘
|
||
/goal Phase 5 진행해줘 ← 그레이박스 테스트 완료 후에만 사용
|
||
```
|
||
|
||
작업 완료 후 `[ ]`를 `[x]`로 업데이트하고 **현재 상태** 블록을 갱신한다.
|