🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

게임 분석과 메트릭스 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2026. 2. 3. · 3 Views

게임 분석과 메트릭스 완벽 가이드

Flutter와 Flame으로 개발한 게임의 성공을 측정하고 개선하는 방법을 배웁니다. Firebase Analytics 연동부터 A/B 테스팅, 리텐션 분석까지 데이터 기반 게임 운영의 모든 것을 다룹니다.


목차

  1. Firebase_Analytics_통합
  2. 커스텀_이벤트_추적
  3. 퍼널_분석
  4. AB_테스팅
  5. 리텐션_메트릭스
  6. 데이터_기반_밸런싱

1. Firebase Analytics 통합

김개발 씨는 첫 번째 모바일 게임을 출시했습니다. 다운로드 수는 꽤 나오는데, 정작 유저들이 게임을 어떻게 플레이하는지 전혀 알 수 없었습니다.

"대체 유저들이 어디서 이탈하는 걸까요?" 답답한 마음에 선배에게 물었더니 돌아온 답은 간단했습니다. "분석 도구를 붙여야지."

Firebase Analytics는 구글이 제공하는 무료 앱 분석 서비스입니다. 마치 게임 속에 투명한 관찰자를 심어두는 것과 같습니다.

유저가 어떤 화면을 보고, 어떤 버튼을 누르고, 어디서 게임을 종료하는지 모든 행동을 기록합니다. 이 데이터를 바탕으로 게임을 개선할 방향을 찾을 수 있습니다.

다음 코드를 살펴봅시다.

// pubspec.yaml에 의존성 추가
// firebase_analytics: ^10.8.0

import 'package:firebase_analytics/firebase_analytics.dart';

class GameAnalytics {
  // 싱글톤 패턴으로 앱 전체에서 하나의 인스턴스 사용
  static final GameAnalytics _instance = GameAnalytics._internal();
  factory GameAnalytics() => _instance;
  GameAnalytics._internal();

  final FirebaseAnalytics _analytics = FirebaseAnalytics.instance;

  // 화면 전환 추적 - 유저가 어떤 화면을 방문하는지 기록
  Future<void> logScreenView(String screenName) async {
    await _analytics.logScreenView(screenName: screenName);
  }

  // 게임 시작 이벤트 기록
  Future<void> logGameStart(String levelId) async {
    await _analytics.logLevelStart(levelName: levelId);
  }

  // 게임 종료 이벤트 기록
  Future<void> logGameEnd(String levelId, int score) async {
    await _analytics.logLevelEnd(levelName: levelId, success: score > 0);
  }
}

김개발 씨는 입사 6개월 차 게임 개발자입니다. 팀에서 처음으로 단독 프로젝트를 맡아 퍼즐 게임을 출시했습니다.

출시 첫 주, 다운로드 수는 5천 건을 넘었습니다. 하지만 기쁨도 잠시, 일주일이 지나자 활성 유저 수가 급격히 줄어들기 시작했습니다.

"왜 유저들이 떠나는 걸까요?" 김개발 씨는 고민에 빠졌습니다. 게임이 재미없는 걸까요?

아니면 너무 어려운 걸까요? 추측만 할 뿐 정확한 원인을 알 수 없었습니다.

선배 개발자 박시니어 씨가 조언했습니다. "지금 네 게임은 눈을 감고 운전하는 것과 같아.

어디로 가는지, 어디서 문제가 생기는지 전혀 모르잖아. Firebase Analytics를 붙여봐." 그렇다면 Firebase Analytics란 정확히 무엇일까요?

쉽게 비유하자면, 마치 마트에 설치된 CCTV와 같습니다. 고객이 어떤 코너에서 오래 머무르는지, 어떤 상품을 집었다가 다시 내려놓는지, 계산대까지 가는 동선이 어떤지를 모두 기록합니다.

이 데이터를 분석하면 상품 배치를 최적화할 수 있습니다. Firebase Analytics도 마찬가지로 유저의 모든 행동을 기록하고 분석할 수 있게 해줍니다.

예전에는 이런 분석 시스템을 직접 구축해야 했습니다. 서버를 세팅하고, 데이터베이스를 설계하고, 대시보드를 만들어야 했습니다.

작은 인디 게임 팀에서는 엄두도 내기 어려운 일이었습니다. 하지만 Firebase Analytics는 무료로 이 모든 것을 제공합니다.

위 코드를 살펴보겠습니다. 먼저 싱글톤 패턴으로 GameAnalytics 클래스를 구현했습니다.

이렇게 하면 앱 어디서든 동일한 인스턴스를 사용하므로 데이터 수집이 일관됩니다. logScreenView 메서드는 유저가 어떤 화면을 방문했는지 기록합니다.

메인 메뉴, 설정 화면, 게임 화면 등 모든 화면 전환을 추적할 수 있습니다. logGameStartlogGameEnd는 Firebase에서 기본 제공하는 게임 전용 이벤트입니다.

실제 현업에서는 어떻게 활용할까요? 예를 들어 스테이지가 50개인 퍼즐 게임을 운영한다고 가정해봅시다.

Analytics 데이터를 보니 유저의 70%가 스테이지 7에서 이탈한다는 것을 발견했습니다. 이제 무엇을 해야 할지 명확해집니다.

스테이지 7의 난이도를 조정하거나, 힌트 시스템을 추가하면 됩니다. 주의할 점도 있습니다.

Firebase Analytics 이벤트는 실시간으로 반영되지 않습니다. 보통 24시간 이내에 대시보드에 나타납니다.

또한 너무 많은 이벤트를 기록하면 데이터가 오히려 노이즈가 될 수 있습니다. 핵심 지표에 집중하는 것이 중요합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. Analytics를 연동한 지 일주일 후, 김개발 씨는 대시보드를 열어보았습니다.

"아, 유저들이 튜토리얼에서 80%나 이탈하고 있었구나!" 문제의 원인을 찾은 김개발 씨는 튜토리얼을 대폭 간소화했고, 리텐션이 두 배로 올랐습니다.

실전 팁

💡 - Firebase 콘솔의 DebugView를 사용하면 개발 중 실시간으로 이벤트를 확인할 수 있습니다

  • 앱 시작 시 Analytics 초기화가 완료될 때까지 기다린 후 이벤트를 기록하세요

2. 커스텀 이벤트 추적

박시니어 씨가 김개발 씨의 Analytics 대시보드를 보다가 고개를 갸웃거렸습니다. "기본 이벤트만 있네?

유저가 어떤 아이템을 구매하는지, 어떤 캐릭터를 선택하는지는 안 보여?" 김개발 씨는 당황했습니다. "그런 것도 추적할 수 있나요?"

커스텀 이벤트는 게임에 특화된 행동을 추적할 수 있게 해줍니다. 마치 일기장에 원하는 내용을 자유롭게 적는 것과 같습니다.

아이템 구매, 캐릭터 선택, 보스 처치 등 게임의 핵심 행동을 정의하고 기록할 수 있습니다. 이 데이터는 게임 밸런싱과 수익화 전략의 핵심 근거가 됩니다.

다음 코드를 살펴봅시다.

class GameAnalytics {
  final FirebaseAnalytics _analytics = FirebaseAnalytics.instance;

  // 커스텀 이벤트: 아이템 구매 추적
  Future<void> logItemPurchase({
    required String itemId,
    required String itemName,
    required int price,
    required String currency, // 'gem', 'gold', 'real_money'
  }) async {
    await _analytics.logEvent(
      name: 'item_purchase',
      parameters: {
        'item_id': itemId,
        'item_name': itemName,
        'price': price,
        'currency': currency,
        'timestamp': DateTime.now().toIso8601String(),
      },
    );
  }

  // 커스텀 이벤트: 보스 전투 결과 추적
  Future<void> logBossBattle({
    required String bossId,
    required bool isVictory,
    required int attemptCount,
    required int playerLevel,
    required Duration battleDuration,
  }) async {
    await _analytics.logEvent(
      name: 'boss_battle',
      parameters: {
        'boss_id': bossId,
        'result': isVictory ? 'victory' : 'defeat',
        'attempt_count': attemptCount,
        'player_level': playerLevel,
        'duration_seconds': battleDuration.inSeconds,
      },
    );
  }
}

김개발 씨는 Firebase Analytics의 기본 이벤트만으로도 많은 것을 알 수 있었습니다. 하지만 게임의 핵심 질문에는 답할 수 없었습니다.

"유저들이 가장 많이 구매하는 아이템은 뭘까?" "어떤 보스에서 가장 많이 실패할까?" 이런 질문에 답하려면 커스텀 이벤트가 필요했습니다. 커스텀 이벤트란 무엇일까요?

마치 의사가 환자에게 맞춤형 건강 기록부를 만드는 것과 같습니다. 기본 건강검진 항목 외에도 그 환자에게 중요한 특별한 지표를 추가로 기록하는 것입니다.

당뇨 환자라면 혈당 수치를, 심장 질환자라면 심박수 변화를 더 자세히 기록합니다. 커스텀 이벤트도 마찬가지로 게임에 특화된 지표를 정의하고 추적합니다.

위 코드에서 logItemPurchase 메서드를 보겠습니다. 단순히 "아이템을 구매했다"는 사실만 기록하는 게 아닙니다.

어떤 아이템인지, 가격은 얼마인지, 어떤 재화로 구매했는지까지 상세히 기록합니다. 이 데이터가 쌓이면 "골드로 구매하는 아이템 중 가장 인기 있는 것"이나 "유료 재화로 가장 많이 구매하는 가격대" 같은 인사이트를 얻을 수 있습니다.

logBossBattle 메서드는 더 흥미롭습니다. 보스 전투의 승패뿐 아니라 시도 횟수, 플레이어 레벨, 전투 시간까지 기록합니다.

만약 특정 보스에서 평균 시도 횟수가 10회를 넘고, 전투 시간이 5분 이상이라면? 그 보스가 너무 어렵다는 신호입니다.

Firebase에서 커스텀 이벤트를 사용할 때 몇 가지 규칙이 있습니다. 이벤트 이름은 영문 소문자와 언더스코어만 사용할 수 있고, 최대 40자입니다.

파라미터는 이벤트당 최대 25개까지 추가할 수 있습니다. 파라미터 값은 문자열이나 숫자만 가능합니다.

실무에서 자주 사용하는 커스텀 이벤트를 소개합니다. 튜토리얼 진행률은 어디서 이탈하는지 파악할 때 유용합니다.

재화 획득 및 소비는 게임 경제 밸런스를 분석하는 데 필수입니다. 광고 시청 완료는 수익화 최적화에 중요합니다.

소셜 기능 사용은 바이럴 효과를 측정합니다. 흔히 하는 실수가 있습니다.

너무 많은 이벤트를 정의하는 것입니다. "모든 것을 추적하면 좋지 않을까?"라고 생각하기 쉽지만, 데이터가 너무 많으면 오히려 중요한 신호를 놓칩니다.

핵심 지표 10개 이내로 시작하고, 필요에 따라 추가하는 것이 좋습니다. 김개발 씨는 커스텀 이벤트를 추가한 후 놀라운 발견을 했습니다.

유저들이 가장 많이 구매하는 아이템은 예상과 달리 가장 비싼 검이 아니라, 저렴한 체력 포션이었습니다. "아, 유저들이 게임을 너무 어려워하는구나." 이 인사이트를 바탕으로 초반 난이도를 조정하자 아이템 구매 패턴도 건강하게 변화했습니다.

실전 팁

💡 - 이벤트 이름은 직관적이고 일관된 네이밍 컨벤션을 사용하세요 (예: category_action)

  • 중요한 이벤트는 전환 이벤트로 등록하면 더 상세한 분석이 가능합니다

3. 퍼널 분석

팀 회의에서 기획자가 질문했습니다. "신규 유저 중 첫 결제까지 도달하는 비율이 얼마나 되나요?" 김개발 씨는 대시보드를 뒤적였지만 명확한 답을 찾을 수 없었습니다.

박시니어 씨가 말했습니다. "퍼널 분석을 해봐야 알 수 있어."

퍼널 분석은 유저가 특정 목표에 도달하기까지 거치는 단계를 깔때기 모양으로 시각화하는 분석 방법입니다. 마치 마라톤 코스에서 각 체크포인트를 통과하는 주자 수를 세는 것과 같습니다.

어느 구간에서 가장 많은 이탈이 발생하는지 파악하면 정확히 어디를 개선해야 하는지 알 수 있습니다.

다음 코드를 살펴봅시다.

// 퍼널 단계 정의
enum FunnelStep {
  appOpen,         // 1단계: 앱 실행
  tutorialStart,   // 2단계: 튜토리얼 시작
  tutorialComplete,// 3단계: 튜토리얼 완료
  firstGamePlay,   // 4단계: 첫 게임 플레이
  firstPurchase,   // 5단계: 첫 구매
}

class FunnelAnalytics {
  final FirebaseAnalytics _analytics = FirebaseAnalytics.instance;

  // 퍼널 단계 기록
  Future<void> logFunnelStep(FunnelStep step, {Map<String, dynamic>? extra}) async {
    await _analytics.logEvent(
      name: 'funnel_${step.name}',
      parameters: {
        'step_number': step.index + 1,
        'step_name': step.name,
        'timestamp': DateTime.now().millisecondsSinceEpoch,
        ...?extra,
      },
    );
  }

  // 퍼널 완주 시간 측정
  Future<void> logFunnelCompletion({
    required FunnelStep fromStep,
    required FunnelStep toStep,
    required Duration duration,
  }) async {
    await _analytics.logEvent(
      name: 'funnel_transition',
      parameters: {
        'from_step': fromStep.name,
        'to_step': toStep.name,
        'duration_seconds': duration.inSeconds,
      },
    );
  }
}

김개발 씨는 "퍼널"이라는 단어를 처음 들었습니다. 박시니어 씨가 설명했습니다.

"퍼널은 깔때기라는 뜻이야. 유저들이 목표에 도달하는 과정을 깔때기 모양으로 그리면 어디서 빠져나가는지 한눈에 보이거든." 비유를 들어 설명해보겠습니다.

놀이공원에 온 방문객 1,000명을 상상해봅시다. 입장은 1,000명이 했지만, 롤러코스터까지 도달하는 사람은 몇 명일까요?

입구에서 500명이 식당으로 빠지고, 300명은 관람차를 타러 갑니다. 결국 롤러코스터에 탑승하는 사람은 200명뿐입니다.

이것이 바로 퍼널입니다. 게임에서의 퍼널도 마찬가지입니다.

앱 설치 → 앱 실행 → 튜토리얼 완료 → 첫 게임 클리어 → 첫 결제까지의 여정에서 각 단계마다 유저가 이탈합니다. 중요한 것은 어느 단계에서 가장 많이 이탈하는지 파악하는 것입니다.

위 코드에서 FunnelStep 열거형을 정의했습니다. 각 단계에 번호를 부여하면 나중에 분석할 때 편리합니다.

logFunnelStep 메서드는 유저가 각 단계에 도달할 때마다 호출합니다. 타임스탬프를 함께 기록하면 각 단계 사이의 소요 시간도 분석할 수 있습니다.

logFunnelCompletion 메서드는 더 세밀한 분석을 위한 것입니다. 예를 들어 튜토리얼 시작부터 완료까지 평균 5분이 걸린다면 적절합니다.

하지만 평균 30분이 걸린다면? 튜토리얼이 너무 길거나 어렵다는 신호입니다.

실제 데이터를 분석해봅시다. 가상의 퍼즐 게임 데이터입니다.

앱 실행 10,000명 중 튜토리얼을 시작한 유저는 8,000명입니다. 20%가 튜토리얼도 시작하지 않고 이탈한 것입니다.

튜토리얼을 완료한 유저는 4,000명입니다. 50%가 튜토리얼 중간에 이탈했습니다.

이것이 바로 개선 포인트입니다. Firebase 콘솔에서는 Funnel 리포트를 직접 만들 수 있습니다.

원하는 이벤트들을 순서대로 나열하면 자동으로 깔때기 차트를 생성합니다. 각 단계별 전환율과 이탈률을 한눈에 확인할 수 있습니다.

퍼널 분석에서 흔히 하는 실수는 너무 많은 단계를 정의하는 것입니다. 단계가 많으면 각 단계별 전환율은 높아 보이지만, 전체적인 문제점을 파악하기 어렵습니다.

핵심 단계 5-7개로 시작하는 것이 좋습니다. 김개발 씨는 퍼널 분석 결과를 보고 깜짝 놀랐습니다.

튜토리얼 완료율이 겨우 30%였습니다. "유저 10명 중 7명이 게임을 제대로 해보지도 않고 떠나는구나." 튜토리얼을 3단계에서 5단계로 나누고, 각 단계마다 보상을 추가했습니다.

한 달 후 튜토리얼 완료율은 65%로 두 배 이상 올랐습니다.

실전 팁

💡 - 퍼널의 각 단계는 명확하고 측정 가능한 행동이어야 합니다

  • 동일 유저의 여정을 추적하려면 user_id를 이벤트 파라미터에 포함하세요

4. AB 테스팅

기획팀에서 새로운 아이디어가 나왔습니다. "첫 구매 유저에게 50% 할인 쿠폰을 주면 어떨까요?" 하지만 반대 의견도 있었습니다.

"할인보다 무료 아이템을 주는 게 낫지 않을까요?" 회의실은 의견으로 가득 찼지만 결론은 나지 않았습니다. 박시니어 씨가 말했습니다.

"의견 대신 데이터로 결정하자. A/B 테스트를 해보는 거야."

A/B 테스팅은 두 가지 이상의 버전을 실제 유저에게 보여주고 어떤 것이 더 효과적인지 데이터로 검증하는 방법입니다. 마치 신약 임상시험에서 진짜 약과 위약을 비교하는 것과 같습니다.

추측이 아닌 실제 유저 행동 데이터를 기반으로 의사결정을 내릴 수 있습니다.

다음 코드를 살펴봅시다.

import 'package:firebase_remote_config/firebase_remote_config.dart';

class ABTestManager {
  final FirebaseRemoteConfig _remoteConfig = FirebaseRemoteConfig.instance;
  final GameAnalytics _analytics = GameAnalytics();

  Future<void> initialize() async {
    // Remote Config 초기화
    await _remoteConfig.setConfigSettings(RemoteConfigSettings(
      fetchTimeout: const Duration(minutes: 1),
      minimumFetchInterval: const Duration(hours: 1),
    ));
    await _remoteConfig.fetchAndActivate();
  }

  // 실험 그룹 확인 (A/B 테스트)
  String getExperimentGroup(String experimentName) {
    return _remoteConfig.getString('${experimentName}_group');
  }

  // 첫 구매 보상 실험 예시
  Future<FirstPurchaseReward> getFirstPurchaseReward() async {
    final group = getExperimentGroup('first_purchase_reward');

    // 실험 노출 이벤트 기록
    await _analytics.logExperimentExposure(
      experimentName: 'first_purchase_reward',
      group: group,
    );

    switch (group) {
      case 'control':
        return FirstPurchaseReward(type: 'none', value: 0);
      case 'discount':
        return FirstPurchaseReward(type: 'discount', value: 50);
      case 'free_item':
        return FirstPurchaseReward(type: 'item', value: 100);
      default:
        return FirstPurchaseReward(type: 'none', value: 0);
    }
  }
}

class FirstPurchaseReward {
  final String type;
  final int value;
  FirstPurchaseReward({required this.type, required this.value});
}

회의실에서 벌어지는 논쟁, 개발자라면 한 번쯤 경험해보셨을 것입니다. "이 버튼은 빨간색이 좋아요." "아니, 초록색이 더 클릭률이 높을 거예요." 각자의 경험과 직관을 내세우지만, 누구 말이 맞는지 알 수 없습니다.

바로 이런 상황에서 A/B 테스팅이 빛을 발합니다. A/B 테스팅을 쉽게 설명하면 이렇습니다.

100명의 유저가 있다고 가정합니다. 50명에게는 빨간 버튼을, 다른 50명에게는 초록 버튼을 보여줍니다.

일주일 후 클릭률을 비교합니다. 빨간 버튼 클릭률이 15%고, 초록 버튼이 25%라면?

데이터가 답을 말해줍니다. 위 코드에서 Firebase Remote Config를 사용했습니다.

Remote Config는 앱을 업데이트하지 않고도 서버에서 설정값을 변경할 수 있는 서비스입니다. A/B 테스트의 그룹 분배를 이 기능으로 관리합니다.

Firebase 콘솔에서 유저의 몇 퍼센트를 어떤 그룹에 배정할지 설정할 수 있습니다. getExperimentGroup 메서드는 현재 유저가 어떤 실험 그룹에 속하는지 반환합니다.

중요한 것은 같은 유저는 항상 같은 그룹에 속해야 한다는 것입니다. 오늘은 빨간 버튼을 보고, 내일은 초록 버튼을 본다면 실험 결과가 의미 없어집니다.

Firebase는 이를 자동으로 보장합니다. logExperimentExposure 호출이 중요합니다.

유저가 실험에 노출되었을 때 이벤트를 기록해야 합니다. 이렇게 해야 나중에 "할인 그룹의 구매 전환율 vs 무료 아이템 그룹의 구매 전환율"을 정확히 비교할 수 있습니다.

A/B 테스팅에서 가장 중요한 것은 통계적 유의성입니다. 10명의 데이터로는 결론을 내릴 수 없습니다.

일반적으로 각 그룹당 최소 수백 명의 데이터가 필요합니다. Firebase의 A/B Testing 기능은 자동으로 통계적 유의성을 계산해줍니다.

흔히 하는 실수 중 하나는 너무 많은 것을 동시에 바꾸는 것입니다. 버튼 색상도 바꾸고, 문구도 바꾸고, 위치도 바꾸면 어떤 변화가 효과를 낸 건지 알 수 없습니다.

한 번에 하나의 변수만 테스트하세요. 김개발 씨의 팀은 첫 구매 보상 실험을 2주간 진행했습니다.

결과는 놀라웠습니다. 50% 할인 쿠폰 그룹의 전환율은 8%, 무료 아이템 그룹은 12%였습니다.

무료 아이템이 압도적으로 효과적이었습니다. 데이터가 결론을 내렸고, 더 이상의 논쟁은 필요 없었습니다.

실전 팁

💡 - 실험 기간은 최소 1-2주, 충분한 샘플 수가 모일 때까지 기다리세요

  • 실험 결과에 확신이 없다면 샘플 수를 늘리거나 실험을 연장하세요

5. 리텐션 메트릭스

월간 리포트를 작성하던 김개발 씨가 기획자에게 물었습니다. "DAU, MAU, 리텐션...

이런 지표들이 정확히 뭔가요?" 기획자가 답했습니다. "유저가 우리 게임에 얼마나 자주, 얼마나 오래 머무는지를 나타내는 지표야.

게임의 건강 상태를 보여주는 체온계 같은 거지."

리텐션 메트릭스는 유저가 게임에 얼마나 지속적으로 참여하는지를 측정하는 지표들입니다. 마치 병원의 건강검진 수치처럼 게임의 전반적인 상태를 진단할 수 있습니다.

DAU, MAU, D1/D7/D30 리텐션 등의 지표를 통해 게임이 유저를 잘 붙잡고 있는지 확인합니다.

다음 코드를 살펴봅시다.

class RetentionAnalytics {
  final FirebaseAnalytics _analytics = FirebaseAnalytics.instance;

  // 일일 활성 유저 세션 기록
  Future<void> logDailySession({
    required String oderId,
    required int sessionCount,
    required int daysSinceInstall,
  }) async {
    await _analytics.logEvent(
      name: 'daily_session',
      parameters: {
        'user_id': oderId,
        'session_count': sessionCount,
        'days_since_install': daysSinceInstall,
        'date': DateTime.now().toIso8601String().substring(0, 10),
      },
    );
  }

  // 리텐션 체크포인트 기록
  Future<void> logRetentionCheckpoint({
    required int day, // D1, D7, D14, D30
    required bool isActive,
  }) async {
    await _analytics.logEvent(
      name: 'retention_d$day',
      parameters: {
        'is_active': isActive ? 1 : 0,
        'checkpoint_day': day,
      },
    );
  }

  // 세션 길이 및 빈도 추적
  Future<void> logSessionMetrics({
    required Duration sessionLength,
    required int dailySessionCount,
  }) async {
    await _analytics.logEvent(
      name: 'session_metrics',
      parameters: {
        'session_length_minutes': sessionLength.inMinutes,
        'daily_session_count': dailySessionCount,
      },
    );
  }
}

게임을 출시하고 다운로드 수가 10만을 넘었습니다. 축하할 일입니다.

하지만 잠깐, 그 유저들이 아직도 게임을 하고 있을까요? 신규 유저를 획득하는 것보다 기존 유저를 유지하는 것이 5배 이상 비용 효율적이라는 말이 있습니다.

리텐션 메트릭스는 바로 이 유저 유지율을 측정합니다. 핵심 지표를 하나씩 살펴보겠습니다.

**DAU(Daily Active Users)**는 하루 동안 앱을 실행한 순 유저 수입니다. **MAU(Monthly Active Users)**는 한 달 동안 앱을 실행한 순 유저 수입니다.

DAU/MAU 비율은 고착도를 나타냅니다. 이 비율이 20%라면 MAU 중 20%가 매일 접속한다는 뜻입니다.

캐주얼 게임은 10-20%, 소셜 게임은 20-30%가 일반적입니다. D1 리텐션은 설치 다음 날 다시 접속한 유저 비율입니다.

게임의 첫인상을 나타냅니다. D7 리텐션은 일주일 후 접속률로, 게임의 중기 매력도를 보여줍니다.

D30 리텐션은 한 달 후 접속률로, 장기적인 게임 수명을 예측합니다. 일반적인 모바일 게임의 기준입니다.

D1 리텐션 40% 이상이면 좋음, D7 리텐션 15% 이상이면 좋음, D30 리텐션 5% 이상이면 좋음입니다. 물론 장르에 따라 다릅니다.

하이퍼캐주얼 게임은 D1이 높지만 D30이 매우 낮고, RPG는 D1이 낮지만 D30이 상대적으로 높습니다. 위 코드의 logRetentionCheckpoint 메서드를 보겠습니다.

유저가 D1, D7, D30 체크포인트에 도달할 때마다 이벤트를 기록합니다. 이 데이터를 집계하면 각 시점의 리텐션율을 계산할 수 있습니다.

세션 길이도 중요한 지표입니다. 유저가 한 번 접속해서 얼마나 오래 플레이하는지를 나타냅니다.

세션이 길다는 것은 게임이 몰입감 있다는 증거입니다. 일일 세션 수는 하루에 몇 번 접속하는지입니다.

세션 수가 많다는 것은 게임이 습관화되었다는 좋은 신호입니다. 리텐션을 개선하는 방법도 있습니다.

D1 리텐션을 높이려면 튜토리얼을 개선하고 첫날 경험을 보상으로 가득 채우세요. D7 리텐션을 높이려면 일일 퀘스트와 연속 출석 보상을 도입하세요.

D30 리텐션을 높이려면 길드, 시즌 시스템 등 장기 목표를 제공하세요. 김개발 씨는 리텐션 데이터를 분석하다가 이상한 패턴을 발견했습니다.

D1 리텐션은 45%로 좋은 편인데, D3에서 급격히 떨어졌습니다. 3일차에 무슨 일이 일어나는 걸까요?

분석해보니 3일차에 스태미나가 바닥나는 유저가 많았습니다. 스태미나 회복 시스템을 조정하자 D7 리텐션이 18%에서 25%로 올랐습니다.

실전 팁

💡 - 리텐션 코호트(동일 시점 가입 유저 그룹)별로 분석하면 업데이트 효과를 정확히 측정할 수 있습니다

  • 리텐션이 급락하는 특정 일차가 있다면 그 시점의 유저 경험을 집중 분석하세요

6. 데이터 기반 밸런싱

박시니어 씨가 대시보드를 보며 한숨을 쉬었습니다. "이 검이 너무 강한 것 같아.

이걸 획득한 유저만 스테이지를 쉽게 깨고 있어." 김개발 씨가 물었습니다. "어떻게 밸런스를 맞춰야 할까요?" 박시니어 씨가 답했습니다.

"감으로 하면 안 돼. 데이터가 정확히 얼마나 강한지 알려줄 거야."

데이터 기반 밸런싱은 유저 행동 데이터를 분석하여 게임의 난이도, 경제, 캐릭터 강약을 조절하는 방법입니다. 마치 의사가 혈액검사 수치를 보고 약 처방량을 결정하는 것과 같습니다.

추측이 아닌 실제 데이터를 기반으로 하기 때문에 더 정확하고 효과적인 밸런싱이 가능합니다.

다음 코드를 살펴봅시다.

class BalancingAnalytics {
  final FirebaseAnalytics _analytics = FirebaseAnalytics.instance;

  // 스테이지 클리어 데이터 수집
  Future<void> logStageResult({
    required String stageId,
    required bool isCleared,
    required int attemptCount,
    required Duration playTime,
    required int playerPower,
    required List<String> usedItems,
  }) async {
    await _analytics.logEvent(
      name: 'stage_balance_data',
      parameters: {
        'stage_id': stageId,
        'is_cleared': isCleared ? 1 : 0,
        'attempt_count': attemptCount,
        'play_time_seconds': playTime.inSeconds,
        'player_power': playerPower,
        'used_items': usedItems.join(','),
        'clear_rate_factor': isCleared ? 1.0 / attemptCount : 0,
      },
    );
  }

  // 아이템/캐릭터 성능 데이터 수집
  Future<void> logCombatPerformance({
    required String characterId,
    required String weaponId,
    required int damageDealt,
    required int damageTaken,
    required int kills,
    required int deaths,
  }) async {
    final kda = deaths > 0 ? kills / deaths : kills.toDouble();

    await _analytics.logEvent(
      name: 'combat_balance_data',
      parameters: {
        'character_id': characterId,
        'weapon_id': weaponId,
        'damage_dealt': damageDealt,
        'damage_taken': damageTaken,
        'kda_ratio': kda,
        'efficiency': damageDealt / (damageTaken + 1),
      },
    );
  }
}

게임 밸런스는 개발자를 가장 괴롭히는 문제 중 하나입니다. "이 보스가 너무 쉬워요"라는 유저가 있는가 하면, "너무 어려워서 못 깨겠어요"라는 유저도 있습니다.

둘 다 같은 보스를 말하는 겁니다. 어떻게 해야 할까요?

정답은 데이터에 있습니다. 개발자의 감각도 중요하지만, 수만 명의 유저 데이터만큼 정확한 지표는 없습니다.

스테이지 난이도 밸런싱부터 살펴보겠습니다. 위 코드의 logStageResult 메서드는 스테이지 클리어 데이터를 수집합니다.

핵심 지표는 클리어율, 평균 시도 횟수, 플레이 타임입니다. 이상적인 스테이지는 클리어율 70-80%, 평균 시도 횟수 2-3회, 플레이 타임 2-5분 정도입니다.

만약 특정 스테이지의 클리어율이 30%에 불과하고, 평균 시도 횟수가 10회를 넘는다면? 그 스테이지는 너무 어렵습니다.

반대로 클리어율 99%에 시도 횟수 1회라면? 너무 쉬워서 유저가 지루해할 수 있습니다.

캐릭터/무기 밸런싱은 더 복잡합니다. logCombatPerformance 메서드를 보면 KDA(킬/데스 비율), 딜량, 피해량 등을 수집합니다.

특정 캐릭터의 KDA가 다른 캐릭터의 2배라면? 그 캐릭터가 지나치게 강력하다는 신호입니다.

흥미로운 지표는 pick ratewin rate의 조합입니다. 픽률이 높고 승률도 높다면 명백히 너프가 필요합니다.

픽률은 낮은데 승률이 높다면? 숙련 유저만 사용하는 캐릭터일 수 있으니 신중하게 판단해야 합니다.

픽률이 높은데 승률이 낮다면? 인기는 있지만 약한 캐릭터이므로 버프를 고려합니다.

게임 경제 밸런싱도 데이터로 관리합니다. 유저가 재화를 얼마나 획득하고 소비하는지 추적합니다.

재화가 쌓이기만 하고 쓸 곳이 없다면 인플레이션이 발생합니다. 반대로 재화 획득이 너무 적으면 유저가 답답함을 느낍니다.

이상적인 비율은 획득:소비가 1:0.7~0.9 정도입니다. 밸런스 패치 후에는 반드시 A/B 테스트before/after 비교를 해야 합니다.

너프했더니 오히려 승률이 올라가는 아이러니한 상황도 있습니다. 유저들이 더 신중하게 플레이하기 때문입니다.

김개발 씨는 데이터를 분석하다가 충격적인 사실을 발견했습니다. 5성 전설 무기 "용의 분노"의 사용자 클리어율이 95%에 달했습니다.

다른 무기 사용자의 평균 클리어율은 60%였습니다. 이 무기 하나가 게임 밸런스를 완전히 무너뜨리고 있었던 것입니다.

공격력을 20% 낮추자 클리어율이 75%로 정상화되었고, 오히려 유저 만족도는 올라갔습니다. 너무 쉬우면 재미없다는 것을 데이터가 증명한 셈입니다.

실전 팁

💡 - 밸런스 변경 전후의 데이터를 최소 2주간 수집해 비교하세요

  • 상위 10%와 하위 10% 유저의 데이터를 따로 분석하면 숙련도별 밸런스를 파악할 수 있습니다

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#Flutter#Firebase Analytics#Game Metrics#A/B Testing#Retention#Data Analytics#Flutter,Flame,Game

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.

함께 보면 좋은 카드 뉴스

AAA급 게임 프로젝트 완벽 가이드

Flutter와 Flame 엔진을 활용하여 AAA급 퀄리티의 모바일 게임을 개발하는 전체 과정을 다룹니다. 기획부터 앱 스토어 출시까지, 실무에서 필요한 모든 단계를 이북처럼 술술 읽히는 스타일로 설명합니다.

빌드와 배포 자동화 완벽 가이드

Flutter 앱 개발에서 GitHub Actions를 활용한 CI/CD 파이프라인 구축부터 앱 스토어 자동 배포까지, 초급 개발자도 쉽게 따라할 수 있는 빌드 자동화의 모든 것을 다룹니다.

게임 보안과 치팅 방지 완벽 가이드

Flutter와 Flame 게임 엔진에서 클라이언트 보안부터 서버 검증까지, 치터들로부터 게임을 보호하는 핵심 기법을 다룹니다. 초급 개발자도 쉽게 따라할 수 있는 실전 보안 코드와 함께 설명합니다.

애니메이션 시스템 커스터마이징 완벽 가이드

Flutter와 Flame 게임 엔진에서 고급 애니메이션 시스템을 구현하는 방법을 다룹니다. 스켈레탈 애니메이션부터 절차적 애니메이션까지, 게임 개발에 필요한 핵심 애니메이션 기법을 실무 예제와 함께 배워봅니다.

Flutter Flame 게임 테스팅과 디버깅 완벽 가이드

Flutter와 Flame 엔진으로 개발한 게임의 품질을 보장하는 테스팅 기법과 디버깅 도구를 다룹니다. 단위 테스트부터 골든 테스트, 크래시 리포팅까지 실무에서 바로 적용할 수 있는 내용을 담았습니다.