Files
ProjectSS/ROADMAP.md

279 lines
16 KiB
Markdown
Raw Permalink 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.
# 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]`로 업데이트하고 **현재 상태** 블록을 갱신한다.