Files
asciinevrdie/docs/plan_monetization_system.md
JiWoong Sul d41dd0fb90 docs: 수익화 시스템 문서 추가
- app-ads.txt 광고 인증 파일
- 수익화 시스템 계획 문서
2026-01-16 20:11:13 +09:00

9.2 KiB

수익화 시스템 설계

메타 정보

  • 문서 버전: 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. 캐릭터 생성 - 굴리기

rollsRemaining:
  default: 5
  min: 0
  max: 5
  recharge: +5 (인터스티셜 광고 시청 후)
  persistence: 저장됨 (0회로 종료 시 재시작해도 0회)

2. 캐릭터 생성 - 되돌리기

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. 장비 손실 확률

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. 부활 시스템

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. 게임 속도

speed_levels:
  - 1x: 기본
  - 2x: 명예의 전당 캐릭터 1명 이상 시 해금
  - 5x: 광고 시청 (5분간) 또는 IAP 구매 시 무제한

speed_boost:
  duration: 300000ms (5분)
  ad: 인터스티셜 6초
  paid_user: 광고 없이 무제한

6. 복귀 보상

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. 아이템 희귀도 (목표)

rarity_distribution:
  common: 34%
  uncommon: 40%
  rare: 20%
  epic: 5%
  legendary: 1%
note: 현재 코드와 다름. ItemService.determineRarity() 수정 필요

데이터 모델

MonetizationState

class MonetizationState {
  final bool adRemovalPurchased;      // IAP 구매 여부
  final int rollsRemaining;           // 굴리기 남은 횟수 (0-5)
  final int undoRemaining;            // 되돌리기 남은 횟수
  final List<Stats>? rollHistory;     // 되돌리기용 히스토리
  final int? autoReviveEndMs;         // 자동부활 버프 종료 시점
  final int? speedBoostEndMs;         // 5배속 종료 시점
  final DateTime? lastPlayTime;       // 마지막 플레이 시각
  final int pendingChests;            // 미개봉 상자 개수
  final int? luckyCharmEndMs;         // 행운 버프 종료 시점
}

DeathInfo 확장

class DeathInfo {
  // 기존 필드
  final String? lostItemName;
  final EquipmentSlot? lostItemSlot;
  final ItemRarity? lostItemRarity;

  // 신규 필드
  final EquipmentItem? lostItem;      // 복구용 전체 장비 정보
}

GameSave 버전

current_version: 3
next_version: 4
migration:
  - add: MonetizationState monetization
  - add: DeathInfo.lostItem

엣지 케이스

케이스 조건 처리
광고 로드 실패 네트워크 오류 재시도 버튼 표시
오프라인 상태 네트워크 없음 광고 버튼 비활성화
광고 중 앱 종료 광고 미완료 보상 미지급
IAP 복원 앱 재설치 구글/애플 구매기록 확인
자동부활 중 종료 버프 활성 중 남은 시간 저장
시간 조작 lastPlayTime > now 복귀 보상 없음
굴리기 0회 종료 rollsRemaining == 0 0회 유지
되돌리기 초과 undoRemaining > historyLength min 적용

디버그 옵션 (kDebugMode 전용)

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: 아이템 희귀도 결정

의존성 패키지

dependencies:
  google_mobile_ads: ^5.0.0  # AdMob
  in_app_purchase: ^3.1.0    # IAP