diff --git a/docs/app-ads.txt b/docs/app-ads.txt new file mode 100644 index 0000000..abdce9d --- /dev/null +++ b/docs/app-ads.txt @@ -0,0 +1 @@ +google.com, pub-6691216385521068, DIRECT, f08c47fec0942fa0 \ No newline at end of file diff --git a/docs/plan_monetization_system.md b/docs/plan_monetization_system.md new file mode 100644 index 0000000..bd7919f --- /dev/null +++ b/docs/plan_monetization_system.md @@ -0,0 +1,395 @@ +# 수익화 시스템 설계 + +## 메타 정보 + +- **문서 버전**: 1.0 +- **최종 수정**: 2026-01-16 +- **상태**: 계획 단계 +- **플랫폼**: Android/iOS (모바일 전용) +- **광고 SDK**: AdMob + +--- + +## Task 리스트 + +### Phase 1: 데이터 구조 (선행 작업) + +- [ ] `MonetizationState` 모델 생성 +- [ ] `DeathInfo.lostItem: EquipmentItem?` 필드 추가 +- [ ] `GameSave` v3 → v4 마이그레이션 +- [ ] 장비 손실 확률 공식 변경: `20% + (level-1) * 8.89%` +- [ ] `ItemService.determineRarity()` 확률 수정: 34/40/20/5/1 + +### Phase 2: AdMob 연동 + +- [ ] `google_mobile_ads` 패키지 추가 +- [ ] `AdService` 클래스 생성 +- [ ] 리워드 광고 로드/표시/콜백 구현 +- [ ] 인터스티셜 광고 로드/표시/콜백 구현 +- [ ] 디버그 빌드 광고 ON/OFF 토글 구현 + +### Phase 3: IAP 연동 + +- [ ] `in_app_purchase` 패키지 추가 +- [ ] 광고 제거 상품 등록 (Google Play / App Store) +- [ ] `IAPService` 클래스 생성 +- [ ] 구매 처리 로직 구현 +- [ ] 구매 복원 로직 구현 +- [ ] 구매 상태 영구 저장 + +### Phase 4: 캐릭터 생성 광고 + +- [ ] 굴리기 횟수 상태 관리 (rollsRemaining) +- [ ] 굴리기 횟수 저장/로드 구현 +- [ ] 되돌리기 히스토리 관리 +- [ ] 되돌리기 횟수 상태 관리 (undoRemaining) +- [ ] 캐릭터 생성 UI 수정: 굴리기 버튼 +- [ ] 캐릭터 생성 UI 수정: 되돌리기 버튼 + +### Phase 5: 부활 시스템 + +- [ ] 사망 시 `DeathInfo.lostItem` 저장 로직 +- [ ] `reviveWithAdReward()` 함수 구현 +- [ ] `reviveWithoutAd()` 함수 구현 +- [ ] 자동부활 버프 상태 관리 (autoReviveEndMs) +- [ ] 자동부활 버프 중 사망 처리 로직 +- [ ] 사망 화면 UI: 광고 부활 버튼 +- [ ] 사망 화면 UI: 일반 부활 버튼 + +### Phase 6: 속도업 + +- [ ] 속도 상태 관리 (1x/2x/5x) +- [ ] 명예의 전당 캐릭터 존재 여부 확인 로직 +- [ ] 5배속 버프 상태 관리 (speedBoostEndMs) +- [ ] 속도 UI: 버튼 표시 로직 +- [ ] 속도 UI: 남은 시간 표시 + +### Phase 7: 복귀 보상 + +- [ ] `lastPlayTime` 저장/로드 구현 +- [ ] 오프라인 시간 계산 로직 +- [ ] 오프라인 진행 시뮬레이션 (1배/2배) +- [ ] 보물 상자 축적 로직 +- [ ] 보물 상자 내용물 생성 로직 +- [ ] 행운의 부적 버프 발동 로직 +- [ ] 복귀 보상 UI: 환영 다이얼로그 +- [ ] 복귀 보상 UI: 상자 오픈 + +### Phase 8: 디버그 기능 + +- [ ] 메인 메뉴: 디버그 옵션 섹션 (kDebugMode) +- [ ] 스타트 화면: 디버그 옵션 섹션 +- [ ] 광고 ON/OFF 토글 +- [ ] IAP 구매 시뮬레이션 토글 +- [ ] 오프라인 시간 시뮬레이션 + +--- + +## 스펙 요약 + +### 광고 유형 + +| ID | 유형 | 길이 | 사용처 | +| -- | ---- | ---- | ------ | +| AD_REWARD_REVIVE | 리워드 | 30초 | 부활 | +| AD_REWARD_UNDO | 리워드 | 30초 | 캐릭터 생성 되돌리기 | +| AD_INTERSTITIAL_ROLL | 인터스티셜 | 6초 | 굴리기 횟수 충전 | +| AD_INTERSTITIAL_SPEED | 인터스티셜 | 6초 | 게임 속도업 | + +### IAP 상품 + +| ID | 가격 | 유형 | +| -- | ---- | ---- | +| remove_ads | $9.99 | 비소모성 (1회 구매) | + +### 무료 vs 구매 유저 비교 + +| 기능 | 무료 유저 | 구매 유저 | +| ---- | --------- | --------- | +| 광고 | 표시 | 제거 (버튼 클릭 시 바로 활성화) | +| 복귀 상자 최대 | 5개 | 10개 | +| 오프라인 진행 속도 | 1배 | 2배 | +| 행운 버프 발동 | 1시간당 5분 | 30분당 5분 | +| 캐릭터 되돌리기 | 1회 (광고) | 3회 (무료) | +| 굴리기 충전 | 광고 필요 | 무제한 | +| 속도업 | 광고 필요 | 무제한 | + +--- + +## 상세 스펙 + +### 1. 캐릭터 생성 - 굴리기 + +```yaml +rollsRemaining: + default: 5 + min: 0 + max: 5 + recharge: +5 (인터스티셜 광고 시청 후) + persistence: 저장됨 (0회로 종료 시 재시작해도 0회) +``` + +### 2. 캐릭터 생성 - 되돌리기 + +```yaml +undoRemaining: + free_user: 1 + paid_user: 3 + ad_required: + free_user: true (30초 리워드) + paid_user: false + range: 1단계 전만 + reset: 새로 굴리기 시작 시 초기화 + constraint: min(undoRemaining, rollHistory.length) +``` + +### 3. 장비 손실 확률 + +```yaml +formula: 20 + (level - 1) * 80 / 9 +level_1: 20% +level_5: 56% +level_10_plus: 100% +code: | + int calculateEquipmentLossChance(int level) { + if (level >= 10) return 100; + return 20 + ((level - 1) * 80 ~/ 9); + } +``` + +### 4. 부활 시스템 + +```yaml +normal_revive: + ad: false + hp_recovery: 50% + equipment_loss: confirmed + sacrifice: required + +ad_revive: + ad: true (30초 리워드) + hp_recovery: 100% + equipment_loss: cancelled (lostItem 복구) + sacrifice: none + auto_revive_buff: + duration: 600000ms (10분) + effect: 버프 중 사망 시 자동부활 + 장비 손실 없음 +``` + +### 5. 게임 속도 + +```yaml +speed_levels: + - 1x: 기본 + - 2x: 명예의 전당 캐릭터 1명 이상 시 해금 + - 5x: 광고 시청 (5분간) 또는 IAP 구매 시 무제한 + +speed_boost: + duration: 300000ms (5분) + ad: 인터스티셜 6초 + paid_user: 광고 없이 무제한 +``` + +### 6. 복귀 보상 + +```yaml +offline_progress: + free_user: 1x + paid_user: 2x + +treasure_chest: + rate: 1개/시간 + max_free: 5개 + max_paid: 10개 + contents: + equipment: 50% + gold: 30% + potion: 15% + bonus_equipment: 5% + +lucky_charm_buff: + free_user: 5분/오프라인1시간 + paid_user: 5분/오프라인30분 + max_duration: 30분 + effect: + common: 34% → 28% + uncommon: 40% → 40% + rare: 20% → 20% + epic: 5% → 10% + legendary: 1% → 2% +``` + +### 7. 아이템 희귀도 (목표) + +```yaml +rarity_distribution: + common: 34% + uncommon: 40% + rare: 20% + epic: 5% + legendary: 1% +note: 현재 코드와 다름. ItemService.determineRarity() 수정 필요 +``` + +--- + +## 데이터 모델 + +### MonetizationState + +```dart +class MonetizationState { + final bool adRemovalPurchased; // IAP 구매 여부 + final int rollsRemaining; // 굴리기 남은 횟수 (0-5) + final int undoRemaining; // 되돌리기 남은 횟수 + final List? rollHistory; // 되돌리기용 히스토리 + final int? autoReviveEndMs; // 자동부활 버프 종료 시점 + final int? speedBoostEndMs; // 5배속 종료 시점 + final DateTime? lastPlayTime; // 마지막 플레이 시각 + final int pendingChests; // 미개봉 상자 개수 + final int? luckyCharmEndMs; // 행운 버프 종료 시점 +} +``` + +### DeathInfo 확장 + +```dart +class DeathInfo { + // 기존 필드 + final String? lostItemName; + final EquipmentSlot? lostItemSlot; + final ItemRarity? lostItemRarity; + + // 신규 필드 + final EquipmentItem? lostItem; // 복구용 전체 장비 정보 +} +``` + +### GameSave 버전 + +```yaml +current_version: 3 +next_version: 4 +migration: + - add: MonetizationState monetization + - add: DeathInfo.lostItem +``` + +--- + +## 엣지 케이스 + +| 케이스 | 조건 | 처리 | +| ------ | ---- | ---- | +| 광고 로드 실패 | 네트워크 오류 | 재시도 버튼 표시 | +| 오프라인 상태 | 네트워크 없음 | 광고 버튼 비활성화 | +| 광고 중 앱 종료 | 광고 미완료 | 보상 미지급 | +| IAP 복원 | 앱 재설치 | 구글/애플 구매기록 확인 | +| 자동부활 중 종료 | 버프 활성 중 | 남은 시간 저장 | +| 시간 조작 | lastPlayTime > now | 복귀 보상 없음 | +| 굴리기 0회 종료 | rollsRemaining == 0 | 0회 유지 | +| 되돌리기 초과 | undoRemaining > historyLength | min 적용 | + +--- + +## 디버그 옵션 (kDebugMode 전용) + +```yaml +debug_options: + ad_enabled: + type: bool + default: true + off_behavior: 광고 버튼 클릭 시 바로 보상 + on_behavior: 실제 광고 재생 + + iap_simulated: + type: bool + default: false + off_behavior: 무료 유저로 동작 + on_behavior: 구매 유저로 동작 + + offline_hours: + type: int + options: [0, 1, 5, 10] + default: 0 + purpose: 복귀 보상 테스트 + +locations: + - 메인 메뉴 (광고 제거 버튼 아래) + - 스타트 화면 +``` + +--- + +## UI 요약 + +### 메인 메뉴 + +``` +[ 새 게임 ] +[ 불러오기 ] +[ 설정 ] +[ 명예의 전당 ] +──────────── +[ 광고 제거 - $9.99 ] ← 구매 후 비활성화 +── Debug Only ── +[ 광고: ON/OFF ] +[ IAP: 미구매/구매 ] +``` + +### 캐릭터 생성 + +``` +STR: 14 CON: 12 DEX: 10 +INT: 16 WIS: 8 CHA: 11 +Total: 71 + +[ 굴리기 (N/5) ] ← 0회 시 🎬 표시 +[ 🎬 이전으로 (N/M) ] ← 무료:1회, 구매:3회 +``` + +### 게임 화면 - 속도 + +``` +명예의 전당 없음: [ 1x ] [ 🎬 5x ] +명예의 전당 있음: [ 1x ] [ 2x ] [ 🎬 5x ] +5배속 중: [ 5x ⏱️ 4:32 ] +``` + +### 사망 화면 + +``` +☠️ You Died +Killed by: {monster} +Lost: {item} + +[ 🎬 광고 부활 (30초) ] + - 장비 복구 + - 제물 없음 + - HP 100% + - 10분 자동부활 + +[ 일반 부활 ] + - 장비 손실 + - 제물 소모 + - HP 50% +``` + +--- + +## 참고 + +### 관련 파일 + +- `lib/src/core/model/game_state.dart`: GameState 모델 +- `lib/src/core/engine/progress_service.dart`: 사망 처리 로직 +- `lib/src/core/storage/`: 저장/로드 시스템 +- `lib/src/core/engine/item_service.dart`: 아이템 희귀도 결정 + +### 의존성 패키지 + +```yaml +dependencies: + google_mobile_ads: ^5.0.0 # AdMob + in_app_purchase: ^3.1.0 # IAP +```