docs: 게임 시스템 개편 계획 문서 작성
- 기존 문서 doc/bak으로 백업 - 새 계획 문서 game-system-overhaul-plan.md 추가 - Phase 1-10: 전투, 아이템, 스킬, 사망/부활, 종족/클래스 등 - 사운드/음악/진동 시스템 설계 - 업적, 도감, 통계 시스템 설계 - 재미 요소 설계 (데미지 팝업, 콤보, 일일 도전 등) - 피해야 할 요소 정리
This commit is contained in:
19
doc/bak/dfm-extract-notes.md
Normal file
19
doc/bak/dfm-extract-notes.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# DFM Extract Script Usage
|
||||
|
||||
- Input: `example/pq/Config.dfm`
|
||||
- Output: `lib/data/pq_config_data.dart`
|
||||
- Command:
|
||||
```bash
|
||||
dart run tool/dfm_extract.dart
|
||||
```
|
||||
- Expected summary (item counts):
|
||||
- Spells 45
|
||||
- OffenseAttrib 11 / DefenseAttrib 9 / OffenseBad 9 / DefenseBad 14
|
||||
- Weapons 38 / Armors 20 / Shields 16
|
||||
- Specials 37 / ItemAttrib 33 / ItemOfs 51 / BoringItems 42
|
||||
- Monsters 231 / MonMods 16
|
||||
- Races 21 / Klasses 18 / Titles 9 / ImpressiveTitles 13
|
||||
- Notes:
|
||||
- Keeps original string literals and `name|level` style intact.
|
||||
- Keys mirror TMemo names in `Config.dfm` without trailing colons.
|
||||
- Re-run the command after any DFM change to refresh the Dart data.
|
||||
61
doc/bak/progress-quest-flutter-plan.md
Normal file
61
doc/bak/progress-quest-flutter-plan.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# 목표
|
||||
- `example/pq`의 Progress Quest 6.4 싱글플레이 체험을 Flutter로 1:1 재현(게임플레이, 이름 생성, 레벨업/퀘스트/플롯 진행 로직까지 동일).
|
||||
- 온라인/네트워크 기능(서버 선택, 계정/비밀번호, 길드/자랑 업로드, 웹 링크 열기, HTTP 요청)은 전부 제거하거나 더미로 대체한 완전 오프라인 버전 구현.
|
||||
- 기존 데이터(종족, 직업, 스펠, 무기/방어구, 몬스터, 아이템 속성 등)는 원본과 같은 풀셋을 포함시켜 동일한 결과가 나오도록 유지.
|
||||
|
||||
# 참조 소스(원본 Delphi)
|
||||
- 메인 루프/타이머/퀘스트/레벨업: `example/pq/Main.pas`
|
||||
- 캐릭터 생성/주사위 굴림/이름 생성: `example/pq/NewGuy.pas`
|
||||
- 데이터 세트(메모 내용): `example/pq/Config.dfm` (`Spells`, `Weapons`, `Armors`, `Shields`, `Monsters`, `ItemAttrib/ItemOfs`, `Races`, `Klasses`, `Titles`, `ImpressiveTitles` 등)
|
||||
- 네트워크 관련 제거 대상: `example/pq/Web.pas`, `HTTPGet.pas`, `SelServ.pas`, `Login.*`, `Info.*`, `Front.*`(웹 링크 부분), `Main.pas` 내 `Brag`, `Guildify`, `Navigate`, `AuthenticateUrl` 호출부
|
||||
- 자산: `swords.gif`, `crossed_swords_sm.gif`, `screenshots.zip`(참고용), `pq.res`(아이콘 참고)
|
||||
|
||||
# 범위와 비범위
|
||||
- 포함: 캐릭 생성(3d6×6, Re-Roll/Unroll, 자동 이름 생성), 퀘스트/플롯 진행 큐, 몬스터/아이템/장비/스펠 획득, 인카운터 텍스트 큐, 저장/불러오기, 진행 바(Task/Quest/Plot/EXP/Encumbrance), 로그 힌트(툴팁 수준), 기본 UI 흐름(프런트 → 새 게임/불러오기 → 메인 화면).
|
||||
- 제외: 모든 HTTP 통신, 서버/길드/자랑 업로드, 프록시/패스키, 외부 브라우저 열기, 시스템 트레이 연동, Windows 레지스트리/파일 연관.
|
||||
|
||||
# 구현 계획(Flutter)
|
||||
1) 프로젝트 세팅
|
||||
- `flutter create`로 신규 앱 생성(안드로이드/웹/데스크톱 동시 지원), lints/analysis 옵션 활성화.
|
||||
- 의존성: `path_provider`(세이브 파일 위치), `shared_preferences` 또는 로컬 파일 I/O, 필요 시 `intl`(날짜 포맷). 상태 관리는 기본 `ChangeNotifier`/`ValueNotifier` 또는 간단한 `provider`로 최소화.
|
||||
|
||||
2) 데이터 포팅
|
||||
- `Config.dfm`의 TMemo 내용을 파싱해 정적 JSON/const 리스트로 변환(스펠/무기/방어구/몬스터/수식어 등). 파싱 스크립트 작성 후 `lib/data/`에 Dart 소스로 고정.
|
||||
- 종족/직업/칭호/몬스터 레벨 등 숫자 필드는 원본 문자열 포맷(`name|level`) 그대로 저장하여 로직 재현.
|
||||
|
||||
3) 게임 상태/엔진
|
||||
- `GameState` 모델: Traits(이름/종족/직업/레벨), Stats(STR/CON/DEX/INT/WIS/CHA/HP/MP), 장비/스펠/인벤토리, 진행 큐(fQueue), 현재 태스크/퀘스트/플롯 상태, encumbrance.
|
||||
- 주기적 타이머(`Ticker`/`Timer.periodic`)로 `TaskBar` 증분, `Dequeue` 동작, `LevelUp`, `CompleteQuest`, `CompleteAct`, `WinEquip/WinSpell/WinItem/WinStat`, `MonsterTask` 로직을 원본 알고리즘에 맞게 Dart로 포팅.
|
||||
- 난수 처리: `Random` seed를 저장/복원 가능하게 두어 재현성 확보(세이브/로드 포함).
|
||||
- 캐릭 생성: 3d6 롤, Total 색상 규칙, Race/Class 선택, 이름 생성(`GenerateName`), Re-Roll/Unroll 이력 지원.
|
||||
|
||||
4) UI 구성
|
||||
- 프런트 화면: 새 게임/불러오기(파일 선택)/종료 선택. 웹 링크 버튼은 제거하거나 “오프라인 버전” 안내로 대체.
|
||||
- 캐릭터 생성 화면: 원본과 동일한 정보 배치(종족/직업 라디오, 6개 스탯 패널, Total 표시, Reroll/Unroll, Name 입력/자동생성).
|
||||
- 메인 화면: ProgressQuest 레이아웃을 Flutter 위젯으로 재현(ListView/SelectableRows → `ListView.builder` + `ListTile`), 상단 Traits/Stats, Equipment/Spells/Inventory, Task/Quest/Plot/EXP/Encumbrance ProgressBar(LinearProgressIndicator 커스텀), 퀘스트/플롯 리스트, 상태바 텍스트 표시.
|
||||
- 툴팁/힌트: Long-press/`Tooltip` 위젯으로 EXP/Plot/Quest 남은 시간, Encumbrance 등 표시.
|
||||
- 치트 패널/숨김 키 조합은 개발자 메뉴로 옵션화(토글 버튼 또는 디버그 빌드 한정).
|
||||
|
||||
5) 저장/불러오기
|
||||
- 세이브 구조: 원본의 Zlib 압축/컴포넌트 덤프 대신 JSON + GZip(`GZipCodec`)으로 단일 파일(`.pqf` 등) 저장. 기존 `.pq` 파일과는 별도 호환 경고 표시.
|
||||
- 자동 저장 시점: 레벨업, 퀘스트/플롯 완료, 앱 백그라운드/종료 전 후킹(각 플랫폼 라이프사이클 대응).
|
||||
- 불러오기: 파일 피커(웹 제외 시 기본 리스트) + 버전 검증 후 상태 복원.
|
||||
|
||||
6) 네트워크 제거/대체
|
||||
- `Brag`, `Guildify`, `Navigate`, `AuthenticateUrl` 등 호출부는 무력화하거나 UI에서 노출하지 않음.
|
||||
- 서버 선택/로그인/패스키 필드 제거. 관련 설정 값은 로컬 상태로만 유지.
|
||||
- 웹 브라우저 링크 버튼은 “온라인 기능 미지원” 안내 다이얼로그로 교체.
|
||||
|
||||
7) 검증/테스트
|
||||
- 단위 테스트: `LevelUpTime`, `GenerateName`(seed 고정), `MonsterTask`(레벨/수식어 변형), `CompleteQuest` 보상 분배, 인카운트 큐(`Dequeue`) 진행 여부.
|
||||
- 위젯 테스트: 메인 화면 로딩, 진행 바 증가, 세이브/로드 왕복.
|
||||
- 회귀 체크: Delphi 원본과 동일한 RNG seed에서 주요 출력(예: 첫 번째 몬스터 이름/퀘스트 문구/장비 이름) 비교 스냅샷.
|
||||
|
||||
8) 작업 순서 제안
|
||||
1. 데이터 추출 스크립트 작성 → Dart 정적 데이터 생성
|
||||
2. GameState/엔진 포팅 및 단위 테스트 확보
|
||||
3. 캐릭터 생성 UI + 상태 연결
|
||||
4. 메인 화면 레이아웃 구현 → 진행 루프 연동
|
||||
5. 세이브/로드/자동저장 구현
|
||||
6. 네트워크 UI 제거/대체 처리 후 스타일 폴리싱
|
||||
7. 멀티플랫폼 빌드 검증(모바일/데스크톱/웹) 및 최종 회귀 테스트
|
||||
159
doc/bak/progress-quest-tasklist.md
Normal file
159
doc/bak/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