Files
asciinevrdie/ARCHITECTURE.md
JiWoong Sul 0116db1056
Some checks failed
CI / analyze-and-test (push) Has been cancelled
docs: Progress Quest 언급 제거 + README 전면 재작성
- README: 프로젝트 설명, 게임 시스템, 스탯 표 포함 재작성
- CLAUDE.md, ARCHITECTURE.md: PQ 참조 제거
- skill_data, pq_logic, game_state, game_mutations: 주석에서 PQ 언급 제거
- analysis/market-analysis: PQ 언급 제거
2026-03-31 00:22:28 +09:00

9.3 KiB

아키텍처

Ascii Never Die의 시스템 설계 문서.

계층 구조

┌─────────────────────────────────────────────────┐
│                  Presentation                    │
│         features/ (화면, 위젯, 컨트롤러)          │
│  front / new_character / game / arena / settings │
├─────────────────────────────────────────────────┤
│                    Domain                        │
│          core/engine/ (게임 로직 서비스)           │
│          core/model/  (데이터 모델)               │
├─────────────────────────────────────────────────┤
│                     Data                         │
│       data/          (정적 게임 데이터)            │
│       core/storage/  (세이브/설정 저장소)          │
│       core/infrastructure/ (광고, IAP)           │
└─────────────────────────────────────────────────┘

의존 방향: Presentation → Domain → Data (역방향 금지)

핵심 데이터 흐름

ProgressLoop (타이머)
    │
    ▼ tickOnce()
ProgressService.tick()
    │
    ├─→ CombatTickService    (전투 틱 처리)
    ├─→ LootHandler          (전리품 처리)
    ├─→ ExpHandler            (경험치/레벨업)
    ├─→ SkillService          (스킬 진행)
    ├─→ QuestCompletionHandler(퀘스트 완료)
    ├─→ StoryService          (스토리 진행)
    └─→ GameMutations         (상태 변경 적용)
           │
           ▼
      GameState (Stream)
           │
           ├─→ UI 갱신 (StreamBuilder)
           └─→ SaveManager 자동 저장

전투 사이클

TaskGenerator.생성() → 몬스터 조우
    │
    ▼
CombatTickService.처리()
    ├─→ PlayerAttackProcessor (플레이어 공격)
    ├─→ CombatCalculator      (데미지 계산)
    └─→ 결과 판정
         ├─ 승리 → LootHandler → ExpHandler → 다음 태스크
         └─ 패배 → DeathHandler → ResurrectionService

디렉토리별 책임

data/ -- 정적 게임 데이터

Config.dfm에서 추출한 종족, 직업, 스킬, 포션, 스토리 데이터. Dart const로 관리하며 런타임 변경 없음.

파일 역할
pq_config_data.dart 게임 원본 정적 데이터 (몬스터, 아이템, 주문 등)
class_data.dart 직업 정의 + 특성
race_data.dart 종족 정의 + 특성
skill_data.dart 68개 스킬 정의
potion_data.dart 포션 데이터
story_data.dart 스토리/액트 데이터
game_text_l10n.dart 게임 텍스트 다국어 매핑

core/engine/ -- 게임 로직 (30개 서비스)

타이머 기반 메인 루프에서 호출되는 순수 게임 로직. UI 의존 없음.

서비스 역할
progress_loop.dart 타이머 기반 메인 루프 (틱 발행)
progress_service.dart 틱 수신 → 서비스 오케스트레이션
combat_tick_service.dart 전투 틱 처리
combat_calculator.dart 데미지/방어/크리티컬 계산
player_attack_processor.dart 플레이어 공격 처리
death_handler.dart 사망 처리
resurrection_service.dart 부활 처리
loot_handler.dart 전리품 드롭
exp_handler.dart 경험치/레벨업
item_service.dart 아이템 생성/비교
shop_service.dart 상점 매매
market_service.dart 시장 거래
skill_service.dart 스킬 진행/레벨업
skill_auto_selector.dart 스킬 자동 선택
potion_service.dart 포션 수집/사용
quest_completion_handler.dart 퀘스트 완료 처리
story_service.dart 스토리/액트 진행
act_progression_service.dart 액트 전환
arena_service.dart 아레나 랭킹/매칭
arena_combat_simulator.dart 아레나 전투 시뮬레이션
chest_service.dart 보물상자 처리
reward_service.dart 보상 분배
return_rewards_service.dart 복귀 보상 계산
stat_calculator.dart 스탯 총합 계산
task_generator.dart 태스크(전투/이동/상점) 생성
game_mutations.dart GameState 변경 함수
character_roll_service.dart 캐릭터 스탯 롤 (3d6)

core/model/ -- 데이터 모델

freezed + json_serializable로 불변(immutable) 모델 생성. 직렬화/역직렬화 자동 처리.

주요 모델: GameState, SaveData, CombatStats, EquipmentItem, ItemStats, MonetizationState, SkillSystemState, ProgressState, HallOfFame

core/storage/ -- 저장 시스템

파일 역할
save_manager.dart 자동/수동 저장 관리
save_service.dart 세이브 슬롯 CRUD
save_repository.dart 파일시스템 I/O
save_integrity.dart HMAC-SHA256 무결성 검증
settings_repository.dart SharedPreferences 설정
hall_of_fame_storage.dart 명예의 전당 저장
statistics_storage.dart 통계 저장

core/infrastructure/ -- 외부 서비스

파일 역할
ad_service.dart Google AdMob 래퍼 (IAdService 구현)
iap_service.dart in_app_purchase 래퍼 (IIAPService 구현)

features/ -- 화면 (Presentation)

각 화면은 독립된 디렉토리. controllers/managers/pages/widgets로 세분화.

디렉토리 화면 구성
front/ 타이틀/세이브 선택 프론트 스크린, 세이브 피커
new_character/ 캐릭터 생성 종족/직업 선택, 스탯 롤, 이름 입력
game/ 메인 게임 7개 탭 페이지, 모바일/데스크톱 레이아웃
arena/ 아레나 PvP 셋업, 전투, 결과
hall_of_fame/ 명예의 전당 영웅 목록, 상세 정보
settings/ 설정 사운드, 언어, 계정

shared/ -- 공용 컴포넌트

  • animation/ -- ASCII 아트 애니메이션 시스템 (Canvas 기반 렌더링, 캐릭터/몬스터/무기 프레임)
  • widgets/ -- 레트로 UI 위젯 (RetroButton, RetroPanel, RetroProgressBar, RetroDialog 등)
  • theme/ -- ASCII 컬러 팔레트, 레트로 테마 상수

DI 구조

GetIt 서비스 로케이터 패턴으로 인터페이스 기반 의존성 주입.

core/di/
├── service_locator.dart   # GetIt 인스턴스 + 등록
├── i_ad_service.dart      # 광고 서비스 인터페이스
└── i_iap_service.dart     # IAP 서비스 인터페이스
// 등록 (main.dart에서 1회 호출)
sl.registerLazySingleton<IIAPService>(() => IAPService.createInstance());
sl.registerLazySingleton<IAdService>(() => AdService.createInstance());

// 사용
final iap = sl<IIAPService>();

인터페이스를 통해 테스트 시 목(mock) 교체 가능.

수익화 시스템

IAP (인앱결제)

  • 상품: remove_ads_and (광고 제거 + 프리미엄)
  • 구매 상태: flutter_secure_storage에 암호화 저장
  • 영수증 검증: Google Play RSA 서명 로컬 검증 (pointycastle)
  • 앱 재설치 시 자동 복원 지원
  • MonetizationState (freezed 모델)로 구매/광고 상태 통합 관리

AdMob (광고)

  • 리워드 광고: 속도 부스트, 복귀 보상 2배
  • 인터스티셜 광고: 부활 시
  • IAP 구매자는 모든 광고 자동 비활성화
  • 릴리즈 빌드에서 치트 메뉴 완전 차단 (kDebugMode 가드)

저장 시스템

세이브 파일

  • JSON 직렬화 (SaveDatajson_serializable)
  • HMAC-SHA256 체크섬으로 무결성 검증 (save_integrity.dart)
  • 파일시스템 기반 저장 (path_provider)
  • 자동 저장: 레벨업, 퀘스트 완료, 주기적 타이머

설정

  • SharedPreferences로 경량 설정 저장 (사운드, 언어 등)

보안 저장

  • IAP 구매 상태: flutter_secure_storage (플랫폼 키체인/키스토어)

테스트 전략

test/
├── core/
│   ├── engine/          # 게임 엔진 서비스 단위 테스트 (12개)
│   ├── model/           # 모델 직렬화/상태 테스트 (2개)
│   ├── storage/         # 저장소 테스트 (1개)
│   └── util/            # 유틸리티/밸런스 테스트 (3개)
├── features/            # 위젯/컨트롤러 테스트 (3개)
├── regression/          # 결정적 게임 시뮬레이션 회귀 테스트 (1개)
└── helpers/             # 목 팩토리, 테스트 셋업

테스트 원칙

  • 엔진 로직 우선: 게임 엔진 서비스에 집중 (전투, 아이템, 스킬, 상점, 아레나, 포션, 복귀보상)
  • 결정적 시뮬레이션: DeterministicRandom으로 동일 시드 → 동일 결과 보장
  • 목 팩토리: test/helpers/mock_factories.dart로 GameState, CombatStats 등 재사용 가능한 테스트 데이터 제공
  • 회귀 테스트: 전체 게임 루프를 N틱 시뮬레이션하여 밸런스 변경 감지

실행

flutter test                    # 전체 실행
flutter test test/core/engine/  # 엔진 테스트만