1. Phase 2 완료 — 자원 경제 & 덱빌딩
- 파산 문책 시스템: 토큰 마이너스 상태로 결재 시 파산 카운터 증가,
의회에서 단계별 경고 → 미개선 시 다음 의회에서 해임 게임오버
- 오염 카드 등급 확률: 엔트로피/내부저항/대중공황/위험계수 단계에 비례한
S/A/B/C 가중치로 의회 종료 시 오염 카드 자동 주입
(신화/조직저항/사회공황/이사회압박 16종 카드 신규 추가)
- 자산 효과 4종 구현: 성질 변환·시한부 격리·물리적 영구 소각·결재권 강제 행사
(자산 슬롯 클릭으로 발동)
2. Phase 3 완료 — 정치 시스템 & 스토리 페이징
- 글로벌 지부장 12개 파벌이 각자 다른 공식으로 우호도를 계산하는 엔진 추가.
게임 시작 시 5명 무작위 선발, 동맹/파국 성향 임원은 국장의 개입(매수/감사)에 면역
- 내러티브 태그 누적치에 따라 페이즈1(일상/위기) → 페이즈2(작전/극비) 카드 풀이
실시간으로 전환되도록 구현
- 버그 수정: 위험 수용 계수(risk)가 직접 게임오버를 발동시키지만 EndingScreen에
대응 엔딩이 없어 "미확인 종말" 빈 폴백으로 빠지던 문제 (risk는 탄핵 기준치로만 사용하도록 수정)
- 버그 수정: CouncilScreen의 임원 초기화 effect가 매수 액션의 risk 상승으로
재실행되며 방금 강제 전환한 투표 결과를 덮어쓰던 문제 (마운트 시 1회만 초기화하도록 수정)
3. Phase 4 완료 — 멀티 엔딩 & 연대기
- 우선순위 기반 엔딩 판별기(endings.js) 신규: 의회 정치 엔딩 > 내러티브 연쇄 엔딩 >
변주된 붕괴 엔딩(자원 태그 3종 + 토큰 3종) > 기본 붕괴 엔딩, 총 15종 엔딩 카탈로그
- 극단적 파라미터 조기 엔딩: 단일 결재로 파라미터가 급격히 5단계에 도달하면
"돌이킬 수 없는 순간" 즉시 발동
- 엔딩 도감(EndingCodex) 신규 컴포넌트: 해금/미해금(???) 표시,
localStorage(ss_endings_v2)에 엔딩 고유 id 기준으로 영구 저장
- 연대기 팝업에 타임라인(세로선 + 턴별 점) 시각화 추가
4. 내러티브 태그 시스템 재설계
- 기존에는 결재 카드 한 장당 무조건 +1 되던 카운터였으나, "항상 얻는 보상이 아니다"라는
기획 의도에 맞춰 선별된 카드(22/63장)의 좌/우 선택지에만 짧은 키워드를 부여하도록 변경
(cards.csv에 left_narrative/right_narrative 컬럼 추가)
- 연대기 팝업 상단과 엔딩 화면에 수집한 키워드를 칩(chip) 형태로 표시
- 위 재설계로 태그 획득이 희소해진 만큼, 페이즈 전환 문턱을 4/8 → 2/4로 하향 조정
5. 기타
- 로컬 Node.js LTS 설치 및 Playwright 기반 실기 플레이 검증 체계 확립
- ROADMAP.md/CLAUDE.md Phase 상태 갱신 (Phase 0~4 그레이박스 구간 완료,
다음은 외부 플레이어 그레이박스 테스트)
87 lines
1.5 KiB
CSS
87 lines
1.5 KiB
CSS
.ending-screen {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: var(--color-bg);
|
|
color: var(--color-text);
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 40px;
|
|
box-sizing: border-box;
|
|
text-align: center;
|
|
z-index: 200;
|
|
}
|
|
|
|
.ending-content {
|
|
margin: 40px 0;
|
|
background: rgba(255, 255, 255, 0.05);
|
|
padding: 30px;
|
|
border-radius: 12px;
|
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
max-width: 400px;
|
|
}
|
|
|
|
.ending-desc {
|
|
font-size: 18px;
|
|
line-height: 1.6;
|
|
margin-bottom: 20px;
|
|
font-family: var(--font-doc-title);
|
|
}
|
|
|
|
.ending-reason {
|
|
font-size: 14px;
|
|
color: #f87171;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.ending-stats {
|
|
font-size: 14px;
|
|
color: #aaa;
|
|
}
|
|
|
|
.ending-keywords {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 6px;
|
|
justify-content: center;
|
|
margin-top: 12px;
|
|
}
|
|
|
|
.keyword-chip {
|
|
font-size: 12px;
|
|
padding: 4px 10px;
|
|
border-radius: 999px;
|
|
background: rgba(255, 255, 255, 0.08);
|
|
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
color: var(--color-token-info);
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.ending-actions {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
width: 100%;
|
|
max-width: 280px;
|
|
}
|
|
|
|
.codex-btn {
|
|
background: transparent;
|
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
color: var(--color-text);
|
|
padding: 12px 24px;
|
|
font-family: var(--font-ui);
|
|
font-size: 14px;
|
|
cursor: pointer;
|
|
border-radius: 4px;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.codex-btn:hover {
|
|
background: rgba(255, 255, 255, 0.08);
|
|
}
|