Собесов

Кейс — анализ пилы сложности match-3 по балансу хардвалюты и оттока

Кейсы и метрикиGame analyticsСложнаяMiddle

Условие

Пила сложности в match-3 игре — механизм постепенного увеличения уровня сложности, чтобы поддерживать интерес и вызов у игрока. Лёгкие уровни дают чувство уверенности, сложные — чувство вызова.

В файле saw.csv колонки:

  • SawStep — шаг пилы (номер уровня в порядке появления у игрока).
  • cry_per_user — сколько хард-валюты («cry») в среднем тратит игрок на этом шаге.
  • churn — процент игроков, ушедших на этом шаге (от тех, кто его начал).
  • LRC — Level Retry Count в виде доли поражений от всех стартов на шаге (то есть LRC = losses / starts, мера сложности).

Задание: проанализировать пилу с точки зрения баланса хардвалюты и оттока.

Решение

Подход

«Баланс пилы» в game analytics — это поиск шагов, на которых:

  • слишком высокий churn (игрок уходит) — обычно из-за слишком сложного уровня (LRC высок);
  • или слишком высокий расход хардвалюты на бустеры/доп-ходы (cry_per_user высок), что либо «съедает» пользователю free-currency запасы и провоцирует уход, либо принуждает его платить.

Цель — найти шаги-«киллеры» (где пользователи или платят слишком много, или уходят) и шаги-«выпадения» (где сложность резко падает и пользователь скучает).

Шаг 1. Базовая EDA

import pandas as pd
import matplotlib.pyplot as plt
 
df = pd.read_csv("saw.csv").sort_values("SawStep").reset_index(drop=True)
 
# Воронка прохождения (сколько игроков доходит до шага N)
df["survival"] = (1 - df["churn"]).cumprod()
 
# Хардвалюта в расчёте на «дошедшего»
df["cry_per_arriving_user"] = df["cry_per_user"]
 
# Общий «слив» хардвалюты со всех игроков, дошедших до шага
df["cry_total"] = df["survival"] * df["cry_per_user"]
 
print(df.head())

Графики, которые надо построить:

  1. Кривая выживаемости survival(SawStep) — экспоненциальный спад? Или есть «обрывы»?
  2. churn по шагам — где локальные пики? Они и есть проблемные уровни.
  3. LRC vs churn — корреляция: если LRC высокий, игрок чаще проигрывает → больше шансов уйти.
  4. cry_per_user по шагам — где пики расхода хардвалюты?

Шаг 2. Идентификация проблемных шагов

Простые правила-эвристики:

  • «Стенка»: шаги с churn > P95(churn) или LRC > P95(LRC). Это места, где пользователи массово упираются.
  • «Дренаж»: cry_per_user > P90(cry_per_user). Слишком дорогая страница: игроки тратят все накопления.
  • «Болото»: подряд несколько шагов с LRC ≈ 0.05–0.10 (слишком легко) — пользователь скучает, churn растёт без видимой сложности.
df["is_wall"]   = df["churn"]  > df["churn"].quantile(0.95)
df["is_drain"]  = df["cry_per_user"] > df["cry_per_user"].quantile(0.90)
df["is_boring"] = df["LRC"].rolling(5).mean() < 0.10
 
print(df[df.is_wall | df.is_drain].sort_values("SawStep"))

Шаг 3. Связь сложности и оттока

Если LRC и churn сильно коррелируют, гипотеза «слишком сложно — пользователи уходят» подтверждается. Но коррелировать может и cry_per_user:

  • Если игрок не имеет хардвалюты для бустера, он чаще проигрывает → LRC растёт → уходит.
  • Если бустер слишком дешёвый, игрок «прожигает» хардвалюту и потом уходит, когда нет денег на следующий сложный уровень.
print(df[["LRC", "churn", "cry_per_user"]].corr())

Хорошо использовать кросс-табы по группам шагов (1–10, 11–20 и т.д.): в начале игры LRC обычно низкий, в конце — высокий; нужно смотреть аномалии относительно ожидаемого среднего по группе.

Шаг 4. Скоринг шагов

Для приоритизации фиксов даём каждому шагу составной балл «проблемности»:

import numpy as np
 
z = lambda s: (s - s.mean()) / s.std()
df["impact_score"] = (
    1.0 * z(df["churn"])
  + 0.5 * z(df["LRC"])
  + 0.5 * z(df["cry_per_user"])
)
df["arrived_share"] = df["survival"]    # сколько % всех новичков туда доходит
df["business_score"] = df["impact_score"] * df["arrived_share"]
print(df.nlargest(10, "business_score")[["SawStep", "churn", "LRC", "cry_per_user", "business_score"]])

Идея: если шаг 200 «убивает» 30% игроков, но до него доходит 0.5% — фикс не нужен. Если шаг 25 убивает 8%, но доходит 80% — это приоритет №1.

Шаг 5. Выводы и рекомендации

Структура отчёта:

  1. Состояние пилы: общая выживаемость, средняя сложность, расход cry на пройденного игрока.
  2. Топ-5 шагов-«стенок» с LRC > X и высоким churn — снизить сложность (меньше препятствий, больше ходов).
  3. Топ-5 шагов-«дренажей» — пересмотреть стоимость бустеров или сделать уровни менее зависимыми от них.
  4. «Болота» — добавить разнообразия / увеличить challenge.
  5. Приоритизация по business_score — какие фиксы дадут наибольший прирост retention.

Подводные камни

  1. Симпсон в зеркале сезонности. Расход cry в среднем по шагу мог расти из-за акций, а не из-за сложности. Нужно фильтровать когорту (один период, одна версия игры).
  2. Survivorship bias. На дальних шагах остаются только хардкорные игроки — у них cry_per_user ниже и LRC выше. Сравнивать средние «по всем» нельзя.
  3. Ошибки определения churn. churn на шаге = не «закончил играть в игру», а «не сделал следующий шаг в течение N дней». Указывайте окно явно.
  4. Корреляция ≠ причинность. Высокий cry_per_user может быть следствием того, что игрок платит, чтобы пройти, а не причиной оттока. Для каузального анализа нужен A/B (см. вторую часть задания).
  5. Метрика LRC искажается при коротких сессиях. Если игрок попробовал шаг один раз и ушёл, LRC = 1.0 — это не сложность, а «не успел разобраться». Срезайте «попытки=1, время<10s» как outliers.
  6. Хардвалюта vs реальные деньги. «cry_per_user» сама по себе ничего не говорит про монетизацию — нужно сопоставлять с тем, какая доля cry куплена за деньги (paid_cry_share).

Эталонный ответ (структура отчёта)

  1. Общая картина: график выживаемости, средние LRC/churn/cry по интервалам шагов.
  2. Топ проблемных шагов по business_score = (z(churn) + 0.5·z(LRC) + 0.5·z(cry))·survival.
  3. Категоризация проблем: стенка / дренаж / болото.
  4. Гипотезы фиксов для каждой категории.
  5. Связь со второй частью задания: предложить A/B-тест сильной гипотезы (см. отдельную задачу awem-difficulty-curve-ab-test).

Главное на собесе — продемонстрировать декомпозицию «отток по причинам» и приоритизацию по бизнес-влиянию, а не «нарисовать красивые графики».

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти