Files
BlockSeasons/docs/superpowers/specs/2026-06-11-commercial-polish-design.md
T
2026-06-11 20:38:27 +09:00

160 lines
8.6 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.
# Block Seasons — 상용 품질 폴리시 라운드 (Phase 3.5) 설계
날짜: 2026-06-11
상태: 승인됨 (오너 시뮬레이터 플레이 피드백 기반)
## 배경
오너가 Phase 3 빌드를 iOS 시뮬레이터에서 플레이한 뒤 피드백:
1. 인트로가 없어 실제 앱스토어 게임이라는 느낌이 안 듦
2. 그래픽이 더 화려하거나 예뻐야 함
3. 게임성은 만족
4. 결론: 더 상업적이고 전문적으로 발전 필요
5. Firebase/AdMob 계정은 준비됐으나, 수익화 전에 게임성과 UI/UX 발전 우선
비주얼 컴패니언(브라우저 목업)으로 방향을 합의했다. 이 라운드는 **Phase 3.5**로,
완료 후 Phase 4(원격 시즌/분석) → Phase 5(수익화)로 진행한다. 예상 기간 약 1주.
## 합의된 방향 (목업 선택 결과)
| 주제 | 선택 | 비고 |
|---|---|---|
| 비주얼 스타일 | 글로시 타일 + 시즌 일러스트 배경 | Block Blast식 광택 타일 + 시즌마다 배경/팔레트 교체 |
| 시즌 1 배경 톤 | 딥 네이비 + 벚꽃 포인트 | 핑크 배경은 기각 — 대중적인 네이비, 벚꽃은 포인트 파티클만 |
| 인트로 범위 | 표준 상용 | 스플래시 + 시즌 타이틀 카드 + 인터랙티브 튜토리얼. 시네마틱은 보류 |
| 시즌 맵 | 여정 경로 맵 | Candy Crush식 지그재그 경로, 그리드 기각 |
| 게임성 확장 | 엔드리스(클래식) 모드 추가 | 데일리 챌린지는 보류 |
## 1. 비주얼 시스템
### 타일 렌더링 업그레이드 (에셋 불필요)
`board_painter.dart` / `piece_painter.dart` 의 단색 사각형을 광택 타일로 교체:
- 셀마다 선형 그라데이션: 밝은 톤(좌상) → 기본색(중앙) → 어두운 톤(우하)
- 상단 안쪽 하이라이트 (흰색 반투명, 유리 광택 느낌)
- 타일 색상 글로우 (바깥 box-shadow 느낌의 blur 페인트)
- 클리어 애니메이션 시 글로우 강도 상승 → 번쩍이며 소멸
- 모서리 라운딩 유지, 보석(gem) 셀은 더 강한 발광
### SeasonTheme 모델
시즌 팩 JSON에서 테마를 읽어 그래픽 전체를 갈아입히는 구조.
```
SeasonTheme {
backgroundGradient: [Color, Color, Color], // 상→하
accentColor: Color,
particleType: petals | snow | leaves | none,
tilePalette: [8 colors], // 생략 시 기본 팔레트
boardTint: Color,
}
```
- `pack.json``theme` 키에서 파싱 (없으면 시즌 1 기본값). 스키마 버전 유지(additive 변경).
- 시즌 1 기본값: 딥 네이비 그라데이션(#0E1430#16204A#2A2E5E), 벚꽃 파티클, 기존 캔디 팔레트.
- 순수 Dart 모델 (`lib/game/models/`), 색은 int ARGB로 저장해 Flutter 비의존 유지.
### 배경 레이어 (프로시저럴 우선)
- `SeasonBackground` 위젯: 그라데이션 + 떠다니는 파티클(꽃잎)을 CustomPainter로 그림.
- 꽃잎은 벡터로 그림(타원 2개 회전 조합), 느리게 낙하+좌우 흔들림, 6~10개, 저사양 부담 없음.
- 홈 / 시즌 맵 / 게임 화면 공통 적용.
- **AI 일러스트는 선택적 강화**: 나중에 배경 이미지 에셋이 생기면 그라데이션 위 레이어로 끼움.
에셋이 없어도 완성 상태여야 한다. (오너용 이미지 프롬프트는 Phase 6에 제공)
## 2. 인트로
### 스플래시 (Flutter 측, 약 2초)
- 네이티브 스플래시 배경색을 #0E1430으로 통일 (iOS LaunchScreen / Android styles).
- Flutter 첫 화면: 블록 4개(핑크/골드/시안/그린)가 화면 밖에서 날아와 2×2 로고로 조립 →
"BLOCK SEASONS" 텍스트 페이드인 → 홈으로 전환.
- SaveRepository 로딩을 이 시간에 겹쳐 수행 (이미 main에서 비동기 오픈 — 체감 로딩 0초).
### 시즌 타이틀 카드 (1.5초, 탭 스킵)
- 콜드 스타트마다 스플래시 직후 표시: 시즌 그라데이션 배경 + "SEASON 1 / 첫 개화 / 60 스테이지".
- 탭하면 즉시 홈으로. 세션당 1회.
### 인터랙티브 튜토리얼 (첫 플레이 1회)
- 발동 조건: 저장 데이터에 `tutorialDone` 플래그 없음 + 스테이지 1 진입.
- 3스텝:
1. 보드 일부 칸 하이라이트 + 손가락 아이콘이 트레이→보드로 드래그 경로 반복 재생.
해당 위치에 놓을 때까지 다른 입력 무시(스킵 제외).
2. 줄이 완성되도록 유도 → 클리어 순간 축하 연출 + "줄을 채우면 사라져요!"
3. HUD 스포트라이트: 목표(보석)와 이동 횟수 설명 말풍선 → "이제 직접 해보세요!"
- 우상단 스킵 버튼 항상 표시. 완료/스킵 시 `tutorialDone=true` 저장.
- 구현: `TutorialController` 상태머신(순수 Dart, 유닛 테스트) + `TutorialOverlay` 위젯.
- 튜토리얼 전용 고정 시드: 스테이지 1을 결정적 트레이로 시작해 1·2스텝 배치가 항상 성립.
### 다국어
신규 문자열 전부 EN/KO ARB 추가 (튜토리얼 문구, 클래식 모드, 게임오버, 최고 점수 등).
## 3. 여정 경로 맵 (시즌 맵 리디자인)
- 세로 스크롤(아래=스테이지 1, 위=60), 진입 시 현재 스테이지 노드로 자동 스크롤.
- 노드 위치는 스테이지 인덱스의 결정적 함수: x = 중앙 ± 사인파 지그재그, y = 인덱스 × 간격.
스테이지 수와 무관하게 자동 배치.
- 노드 사이 점선 경로를 CustomPainter로 드로잉 (부드러운 베지어 곡선).
- 노드 상태: 완료=금색 글로시 + 별(0~3), 현재=핑크 발광 + "PLAY" 라벨 + 펄스 애니메이션,
잠김=어두운 원 + 자물쇠.
- 상단 고정 헤더: 시즌명 + 총 별 (★ n/180).
- 배경: SeasonBackground 공유 + 위로 갈수록 밝아지는 그라데이션(여정 느낌).
- 기존 `season_map_screen.dart` 교체, 위젯 테스트 갱신.
## 4. 타격감 주스 키트 (게임 화면)
| 요소 | 연출 |
|---|---|
| 블록 배치 | 스케일 1.06→1.0 살짝 눌리는 바운스 (90ms) |
| 줄 클리어 | 셀마다 타일색 스파크 파티클 6~8개 방사 + 셀 축소 소멸 |
| 점수 팝업 | "+250"이 클리어 위치에서 떠오르며 페이드아웃 |
| 콤보 배너 | ×2~3: 골드 텍스트 팝 / ×4~5: 화면 미세 흔들림 + 주황 / ×6+: 무지개 그라데이션 + 강한 흔들림 |
| 승리 | 별 1~3개 순차 등장(스케일 바운스 + 사운드) + 컨페티 낙하 |
| 근접 실패 | 목표 달성률 프로그레스 링 ("87% 달성!") — 기존 설계 항목 구현 |
| 햅틱 | 배치=light, 클리어=medium, 콤보 ×4+=heavy (`HapticFeedback`, 플러그인 불필요) |
- 파티클/팝업은 게임 화면 Stack 위 단일 `EffectsOverlay`로 관리 (fxTick 트리거 재사용).
- 모든 연출은 60fps 유지 검증 (시뮬레이터 + 가능하면 실기기).
## 5. 엔드리스(클래식) 모드
- 홈 버튼 2개: **어드벤처**(주 버튼, 시즌 맵으로) + **클래식**(보조 버튼, 즉시 게임).
- 규칙: 이동 제한·목표 없음. 트레이를 둘 곳이 없으면 게임 오버. 콤보/점수 규칙 동일.
- 엔진: `StageConfig`에 무목표·무제한 설정 추가 (기존 엔진 재사용, 분기 최소).
rescue(보상형 이어하기) 슬롯은 유지 — Phase 5에서 광고 연결.
- 저장: `endless: {bestScore}` 를 세이브 블롭에 추가 (saveVersion 유지, additive).
- 게임 오버 화면: 이번 점수 + 최고 점수 (신기록 시 "NEW BEST!" 연출) + 다시 하기.
- 홈에 최고 점수 표시.
## 6. 이번에 만들지 않는 것
- BGM (저작권 무료 음원 도입은 추후 검토)
- 시즌 오프닝 시네마틱 (시즌 2~3쯤 여유 시)
- 부스터/파워업
- 데일리 챌린지
- AI 일러스트 에셋 자체 (구조만 준비, 제작은 Phase 6)
## 7. 검증
- **유닛**: TutorialController 상태 전이, 엔드리스 게임오버/베스트 갱신, SeasonTheme JSON
라운드트립(테마 누락 시 기본값), 경로 맵 노드 좌표 함수.
- **위젯**: 스플래시→홈 전환, 튜토리얼 오버레이 스텝 진행/스킵, 경로 맵 노드 상태 렌더,
홈 클래식 버튼 → 게임 진입, 게임오버 화면.
- **아키텍처 가드**: `lib/game/` Flutter import 금지 유지 (SeasonTheme는 int ARGB).
- **수동**: 시뮬레이터에서 신규 설치 전체 흐름 — 스플래시 → 시즌 카드 → 홈 → 튜토리얼 →
스테이지 1 클리어 → 맵 복귀 → 클래식 한 판. 60fps, 햅틱은 실기기에서.
## 8. 구현 순서 (계획 문서에서 상세화)
1. 비주얼 시스템 (타일 글로시 + SeasonTheme + 배경 레이어) — 모든 화면의 토대
2. 주스 키트 (파티클/팝업/콤보/햅틱)
3. 인트로 (스플래시 → 시즌 카드 → 튜토리얼)
4. 여정 경로 맵
5. 엔드리스 모드 + 홈 리디자인
6. 통합 검증 + 시뮬레이터 빌드