feat: 초기 커밋
- Progress Quest 6.4 Flutter 포팅 프로젝트 - 게임 루프, 상태 관리, UI 구현 - 캐릭터 생성, 인벤토리, 장비, 주문 시스템 - 시장/판매/구매 메커니즘
This commit is contained in:
159
doc/progress-quest-tasklist.md
Normal file
159
doc/progress-quest-tasklist.md
Normal file
@@ -0,0 +1,159 @@
|
||||
# Progress Quest Flutter Task List
|
||||
- 목적: `example/pq`의 Progress Quest 6.4를 Flutter로 오프라인 상태에서 동일하게 재현한다.
|
||||
- 원본 알고리즘/데이터 변형 금지. 변경 필요 시 먼저 사용자 동의.
|
||||
- 작업 중에는 진행된 항목의 체크박스를 즉시 갱신한다.
|
||||
|
||||
## 1) 프로젝트 골격 및 도구
|
||||
- [x] `flutter create`로 새 앱 생성(안드로이드/웹/데스크톱 포함), 루트에 배치 후 기본 샘플 제거.
|
||||
- [x] `analysis_options.yaml`에서 `flutter_lints` 활성화 및 레벨 조정(필요 시).
|
||||
- [x] 의존성 합의 후 추가(`path_provider`, `shared_preferences`/파일 I/O, `intl` 필요 시) — 의존성은 추가함, `pubspec.yaml` 자산 경로 예약 완료.
|
||||
- [x] CI/로컬 명령 정리: `dart format --set-exit-if-changed .`, `flutter analyze`, `flutter test` 기본 스크립트 문서화.
|
||||
|
||||
## 2) 원본 데이터 추출·정적화
|
||||
- [x] `example/pq/Config.dfm`의 TMemo 블록을 파싱하는 스크립트 작성(`tool/dfm_extract.dart`).
|
||||
- [x] 추출 결과를 원본 포맷 그대로 유지(`name|level` 등)한 정적 Dart/JSON으로 변환 후 `lib/data/`에 커밋.
|
||||
- [x] 스펠/무기/방어구/방패/몬스터/수식어/종족/직업/칭호 등 모든 리스트가 원본 개수와 일치하는지 검증 로그 남기기.
|
||||
- [x] 추출 스크립트 사용법과 검증 결과를 `doc/`에 간단히 기록.
|
||||
|
||||
## 3) 엔진/상태 모델 포팅 ✅ (100% 완료)
|
||||
- [x] `GameState`/도메인 모델 정의: Traits, Stats, Equip/Spells/Inventory, 진행 큐(fQueue), Task/Quest/Plot/Exp/Encumbrance 상태, RNG seed.
|
||||
- [x] RNG 시드 저장/복원 로직 구현(`Random` 재생성), 세이브/로드에 포함.
|
||||
- [x] 주요 함수 포팅: `LevelUpTime`, `GenerateName`, `Indefinite/Definite/Plural`, `SpecialItem/InterestingItem/BoringItem`, `WinSpell`, `WinItem`, `WinEquip`, `WinStat`, `MonsterTask`, `CompleteQuest`, `CompleteAct`, `Task`, `Dequeue` 완료.
|
||||
- [x] 보상 적용/장비·스펠·아이템·스탯 변이 헬퍼(GameMutations/RewardService) 추가.
|
||||
- [x] 진행 서비스(ProgressService) 초안: Quest/Act 보상 적용 및 진행 바 리셋/큐 추가.
|
||||
- [x] ProgressState/QueueState 연동 타이머 틱 + Exp/Encumbrance 재계산 + 치트/자동저장 훅 구현(ProgressService.tick/ProgressLoop).
|
||||
- [x] 치트 플래그는 개발자 옵션으로 격리(기본 비활성). — `GameSessionController.cheatsEnabled` 구현됨
|
||||
- [x] 타이머 루프(`Timer.periodic` 또는 `Ticker`)로 TaskBar 증분 및 `Dequeue` 호출, 경과 시간 처리(`timeGetTime` 대체) 구현.
|
||||
- [x] `InterplotCinematic()` 포팅 — 플롯 진행 스토리 생성 (원본 Main.pas:456-493)
|
||||
- [x] `ImpressiveGuy()` 포팅 — NPC 이름 생성 (원본 Main.pas:514)
|
||||
|
||||
## 4) UI 흐름 구현 🟡 (60% 완료)
|
||||
|
||||
### 4.1) 캐릭터 생성 화면 (NewCharacterScreen) ✅ 완료
|
||||
|
||||
- [x] 종족 선택 RadioGroup (21개): Half Orc, Double Hobbit, Gobhoblin 등
|
||||
- [x] 직업 선택 RadioGroup (18개): Ur-Paladin, Voodoo Princess, Robot Monk 등
|
||||
- [x] 능력치 굴림 (3d6×6): STR/CON/DEX/INT/WIS/CHA + Total 표시
|
||||
- [x] Total 색상 규칙: 81+ 빨강, 72+ 노랑, 45- 회색, 54- 은색, 그 외 흰색
|
||||
- [x] Re-Roll/Unroll 버튼 (이력 관리)
|
||||
- [x] 이름 입력 + Gen 버튼 (`generateName()` 연동)
|
||||
- [x] "Sold!" 버튼으로 GameState 생성 및 게임 시작
|
||||
|
||||
### 4.2) 게임 진행 화면 (GamePlayScreen) ✅ 기본 완료
|
||||
|
||||
- [x] 3패널 레이아웃 구성 (원본 Main.dfm 기준)
|
||||
- [x] **좌측 패널 (Character Sheet)**:
|
||||
- [x] Traits ListView (이름, 종족, 직업, 레벨)
|
||||
- [x] Stats ListView (STR/CON/DEX/INT/WIS/CHA + HP Max/MP Max)
|
||||
- [x] Experience ProgressBar
|
||||
- [x] Spell Book ListView (스펠 이름 + 로마 숫자 랭크)
|
||||
- [x] **중앙 패널 (Equipment/Inventory)**:
|
||||
- [x] Equipment ListView (Weapon/Shield/Armor)
|
||||
- [x] Inventory ListView (아이템 이름 + 수량)
|
||||
- [x] Encumbrance ProgressBar
|
||||
- [x] **우측 패널 (Plot/Quest)**:
|
||||
- [x] Plot Development ListView (액트 목록)
|
||||
- [x] Plot ProgressBar
|
||||
- [x] Quests ListView (현재 퀘스트)
|
||||
- [x] Quest ProgressBar
|
||||
- [x] **하단 (Status Bar)**:
|
||||
- [x] Task ProgressBar + 현재 작업 텍스트
|
||||
- [x] 상태 메시지
|
||||
|
||||
### 4.3) 프런트 화면 (FrontScreen) 개선 ✅ 완료
|
||||
|
||||
- [x] "New Character" 버튼 → NewCharacterScreen 연결
|
||||
- [x] "Load Game" 버튼 → 저장 파일 로드 연결
|
||||
- [x] 파일 피커 UI 추가 (다중 세이브 슬롯 지원)
|
||||
|
||||
### 4.4) 화면 네비게이션 ✅ 완료
|
||||
|
||||
- [x] 라우터 설정: FrontScreen → NewCharacterScreen → GamePlayScreen
|
||||
- [x] 저장 파일 로드 시 직접 GamePlayScreen 이동
|
||||
- [x] 뒤로가기/종료 처리 개선 (PopScope + 저장 확인 다이얼로그)
|
||||
|
||||
### 4.5) 부가 UI ✅ 완료
|
||||
|
||||
- [x] 툴팁/힌트: EXP/Plot/Quest 남은 시간을 `Tooltip`으로 표시.
|
||||
- [x] 치트 패널은 디버그 전용 토글로 감추기(cheatsEnabled 플래그로 제어).
|
||||
|
||||
## 5) 저장/불러오기 ✅ (100% 완료)
|
||||
|
||||
- [x] 세이브 포맷 결정 및 구현: JSON + GZip(`GZipCodec`) 단일 파일(`.pqf`), RNG seed 포함. (`GameSave` 직렬화 + SaveService 구현)
|
||||
- [x] 저장 시점: 레벨업, 퀘스트/플롯 완료 시 자동 저장. (AutoSaveConfig로 구현됨)
|
||||
- [x] 실패 처리: 예외/손상 파일 시 사용자 피드백 및 안전한 종료 흐름. (SaveRepository에 오류 결과 반환)
|
||||
- [x] SaveManager: GameState <-> 파일 입출력 상위 래퍼 추가 (`progress.pqf` 기본 파일명).
|
||||
- [x] SaveManager를 레벨업/퀘스트/액트 완료/루프 중단 시 자동 저장하도록 엔진(ProgressLoop)과 연결.
|
||||
- [x] GameSessionController(프리젠테이션 레이어)로 ProgressLoop/SaveManager 제어 및 상태 구독 토대 마련(향후 UI 연결 필요).
|
||||
- [x] 불러오기: 파일 피커 UI로 다중 세이브 슬롯 지원.
|
||||
- [x] 파일 피커/로드 오류 메시지 처리 및 UI 연결.
|
||||
- [x] 앱 백그라운드/종료 감지 시 자동 저장 (WidgetsBindingObserver 연동)
|
||||
|
||||
## 6) 네트워크 제거/대체 ⏸️ (보류 - 오프라인 전용 구현)
|
||||
|
||||
- [x] 온라인 관련 코드 포팅하지 않음 (Web.pas, SelServ.pas, Login.pas 제외)
|
||||
- [ ] UI에서 "오프라인 버전" 안내 다이얼로그 추가 (선택사항)
|
||||
|
||||
## 7) 자산 정리 ✅ (완료 - Material Icons 사용)
|
||||
|
||||
- [x] 원본 자산 확인: `swords.gif`, `crossed_swords_sm.gif`, `pq.res` (example/pq에 참조용 유지)
|
||||
- [x] **정책**: CLAUDE.md "이미지 파일 미사용" 규칙에 따라 Material Icons로 대체
|
||||
- `Icons.auto_awesome` - 타이틀 아이콘
|
||||
- `Icons.casino_outlined` - 새 캐릭터 버튼
|
||||
- `Icons.folder_open` - 로드 버튼
|
||||
- 기타 Material Icons 활용
|
||||
|
||||
## 8) 테스트·회귀 검증 ✅ (100% 완료)
|
||||
|
||||
- [x] 단위 테스트: `LevelUpTime`, `GenerateName`(고정 시드), `MonsterTask`(레벨/수식어 조합), `CompleteQuest` 보상, `Dequeue` 진행 확인.
|
||||
- [x] 단위 테스트: 진행 틱/레벨업/퀘스트 완료 및 ProgressLoop 자동저장 동작 추가.
|
||||
- [x] GameSessionController 테스트: 새 게임 시작, 로드 오류 처리, 일시정지 저장 (3개 통과)
|
||||
- [x] 위젯 테스트: NewCharacterScreen (5개), GamePlayScreen (6개), FrontScreen (1개) 추가.
|
||||
- [x] 원본 대비 회귀 체크: 동일 시드(42, 100, 999)에서 스냅샷 비교 검증 완료 (`test/regression/deterministic_game_test.dart`)
|
||||
- generateName, monsterTask, namedMonster, winEquip, winSpell, winItem, completeQuest 결정적 출력 검증
|
||||
- Config Data 개수 검증: races(21), klasses(18), monsters(231), spells(45), weapons(38), armors(20), shields(16)
|
||||
|
||||
**현재 테스트 현황**: 50개 테스트 모두 통과
|
||||
|
||||
## 9) 검증 및 문서화 ✅ (100% 완료)
|
||||
|
||||
- [x] `dart format --set-exit-if-changed .` 실행 (포맷 적용됨)
|
||||
- [x] `flutter test` 실행 (50개 테스트 모두 통과)
|
||||
- [x] `flutter analyze` - **No issues found!**
|
||||
- deprecated 경고 수정: `surfaceVariant` → `surfaceContainerHighest`, `withOpacity` → `withValues`
|
||||
- prefer_single_quotes 수정: `dart fix --apply` 로 647개 수정
|
||||
- 테스트 파일 lint 수정: `fake_async` 의존성 추가, 로컬 변수명 규칙 준수
|
||||
- [x] 변경 사항/검증 결과/제약사항 업데이트 완료
|
||||
|
||||
---
|
||||
|
||||
## 구현 파일 현황
|
||||
|
||||
### 완료된 핵심 파일
|
||||
|
||||
| 파일 | 줄 수 | 상태 |
|
||||
|------|-------|------|
|
||||
| `lib/src/core/engine/progress_service.dart` | 296 | ✅ |
|
||||
| `lib/src/core/engine/progress_loop.dart` | 124 | ✅ |
|
||||
| `lib/src/core/engine/game_mutations.dart` | 86 | ✅ |
|
||||
| `lib/src/core/engine/reward_service.dart` | 26 | ✅ |
|
||||
| `lib/src/core/model/game_state.dart` | 380 | ✅ |
|
||||
| `lib/src/core/model/save_data.dart` | 237 | ✅ |
|
||||
| `lib/src/core/util/pq_logic.dart` | 664 | ✅ |
|
||||
| `lib/src/core/util/deterministic_random.dart` | 38 | ✅ |
|
||||
| `lib/src/core/util/roman.dart` | 83 | ✅ |
|
||||
| `lib/src/core/storage/save_*.dart` | 121 | ✅ |
|
||||
| `lib/data/pq_config_data.dart` | 675 | ✅ |
|
||||
| `lib/src/features/game/game_session_controller.dart` | 117 | ✅ |
|
||||
| `lib/src/features/new_character/new_character_screen.dart` | 486 | ✅ 신규 |
|
||||
| `lib/src/features/game/game_play_screen.dart` | 420 | ✅ 신규 |
|
||||
| `lib/src/app.dart` (라우터 포함) | 108 | ✅ 수정 |
|
||||
| `lib/src/features/front/front_screen.dart` | 318 | ✅ 수정 |
|
||||
|
||||
### 남은 작업
|
||||
|
||||
| 작업 | 우선순위 |
|
||||
|------|---------|
|
||||
| (선택) "오프라인 버전" 안내 다이얼로그 | 🟢 선택사항 |
|
||||
|
||||
**🎉 핵심 기능 100% 완료!**
|
||||
Reference in New Issue
Block a user