MAATRIX GAMES / Блог / Удержание игроков: метрики и аналитика сервера

Удержание игроков: метрики и аналитика сервера

MAATRIX GAMES

«Онлайн вроде стабильный, а сервер как будто умирает» — знакомое ощущение почти любому админу, который держит проект дольше пары месяцев. Проблема в том, что просто число «сейчас на сервере 40 человек» ничего не говорит о здоровье сообщества: это могут быть 40 постоянных игроков, которые заходят третий месяц подряд, а может — 40 новых лиц, из которых до следующей недели не доживёт и десяток. Разница между этими сценариями решается не интуицией, а конкретными метриками, которые несложно считать даже без Grafana и выделенной аналитической базы.

Почему просто «онлайн» — плохая метрика

Пиковый онлайн — это метрика тщеславия: она хорошо смотрится на скриншоте для рекламы, но не помогает принимать решения. Сервер может держать 60 человек в пятницу вечером и при этом терять большую часть новичков после первого захода — просто за счёт того, что реклама или поисковая выдача постоянно приводит свежий трафик, который маскирует реальный отток под графиком стабильного онлайна.

Три вещи, которые онлайн-число не показывает:

  • сколько из сегодняшних игроков были здесь неделю назад (это и есть retention);
  • растёт сообщество органически или держится исключительно на новых заходах;
  • в какой момент отток стал больше притока — по одному онлайну это видно только постфактум, когда сервер уже полупустой.

Отсюда практический вывод: нужен минимум один слой данных глубже — история подключений по каждому игроку, а не агрегированный счётчик «сколько человек сейчас».

Retention: D1, D7, D30 и как их считать

Retention (возврат) отвечает на вопрос «сколько игроков, зашедших в день X, вернулись через N дней». Стандартный набор для игровых серверов — D1 (вернулся на следующий день), D7 (вернулся в течение недели) и D30 (вернулся в течение месяца). Это метрики из мобильного геймдева, но они прямо переносятся на игровые серверы: D1 показывает, зацепил ли сервер игрока в первую сессию, D7 — прижился ли он в сообществе, D30 — стал ли постоянным.

Формула когортного retention для конкретного дня:

D1(day) = (игроки из когорты day, зашедшие на day+1) / (игроки в когорте day) × 100%

Считается это по когортам — группам игроков, впервые зашедших в один и тот же день. Нужна таблица логов подключений минимум с полями player_id, first_seen, login_time. Если под рукой SQLite (см. подход из статьи про Discord-бота для статистики онлайна — там как раз описана база для истории онлайна), запрос на D1 по когорте новичков выглядит так:

-- когорта: игроки, впервые зашедшие вчера
WITH cohort AS (
  SELECT player_id, DATE(first_seen) AS cohort_day
  FROM players
  WHERE DATE(first_seen) = DATE('now', '-1 day')
),
returned AS (
  SELECT DISTINCT l.player_id
  FROM logins l
  JOIN cohort c ON c.player_id = l.player_id
  WHERE DATE(l.login_time) = DATE('now')
)
SELECT
  (SELECT COUNT(*) FROM cohort) AS cohort_size,
  (SELECT COUNT(*) FROM returned) AS returned_d1,
  ROUND(100.0 * (SELECT COUNT(*) FROM returned) / NULLIF((SELECT COUNT(*) FROM cohort), 0), 1) AS d1_pct;

Ориентировочно (это именно ориентир, не измеренное значение, и сильно зависит от жанра и того, насколько сервер «залипательный» с первой минуты): для community-серверов Minecraft и Rust здоровым считается D1 в районе 25-40%, D7 — 10-20%, D30 — 5-10%. Для узкоспециализированных RP-проектов с высоким порогом входа (whitelist, собеседование, лор) цифры обычно ниже по D1, но выше по D7 — те, кто прошёл отбор, реже уходят сразу.

Нужен игровой сервер?

MAATRIX GAMES — 45+ игр, деплой за минуты, DDoS-защита, автобэкапы. Тарифы от 399 ₽/мес.

Создать сервер

Пиковый и средний онлайн по дням недели

Помимо retention нужна вторая ось — распределение активности по времени. Один общий пиковый онлайн скрывает то, что реально важно: во сколько сервер живёт, а во сколько там три человека и бот. Без этого невозможно ни грамотно ставить рестарт/вайп, ни планировать ивенты.

Минимальный набор, который стоит копить — часовые срезы онлайна за 4-6 недель, сведённые в таблицу «день недели × час». Если история онлайна уже собирается ботом (см. предыдущую ссылку), агрегация делается одним запросом:

SELECT
  CAST(strftime('%w', ts) AS INTEGER) AS weekday, -- 0=вс, 6=сб
  CAST(strftime('%H', ts) AS INTEGER) AS hour,
  AVG(online) AS avg_online,
  MAX(online) AS peak_online
FROM online_history
WHERE ts >= datetime('now', '-42 days')
GROUP BY weekday, hour
ORDER BY weekday, hour;

На выходе получается тепловая карта: обычно у community-серверов два явных пика — будний вечер (19:00-23:00 по основному часовому поясу аудитории) и выходные с 14:00 до полуночи, с провалом в рабочие дневные часы. Конкретные часы зависят от того, из какого региона основная аудитория — для RU-комьюнити это, как правило, МСК+0/+3, для проектов с международной аудиторией картина размывается на два-три пика. Если сервер стоит на локации, отличной от аудитории (например, US-нода для RU-игроков ради лучшего пинга до определённого региона — тема отдельная и решается выбором ближайшей локации при заказе сервера), это на онлайн не влияет, а вот на пинг конкретных игроков — вполне.

Практическая польза этой таблицы: рестарт/вайп ставится в реальное мёртвое окно (обычно это 6-10 утра будних дней), а не «на глаз в 4 утра по умолчанию», а ивенты анонсируются на пиковые часы, а не когда удобно админу.

Churn: отток и его ранние признаки

Churn — доля игроков, переставших заходить, за период. Считается зеркально к retention:

churn_30d = 1 - (активные в последние 30 дней ИЗ ТЕХ, кто был активен 30-60 дней назад)
WITH prev_active AS (
  SELECT DISTINCT player_id FROM logins
  WHERE login_time BETWEEN datetime('now', '-60 days') AND datetime('now', '-30 days')
),
still_active AS (
  SELECT DISTINCT l.player_id FROM logins l
  JOIN prev_active p ON p.player_id = l.player_id
  WHERE l.login_time >= datetime('now', '-30 days')
)
SELECT
  (SELECT COUNT(*) FROM prev_active) AS base,
  (SELECT COUNT(*) FROM still_active) AS retained,
  ROUND(100.0 * (1 - CAST((SELECT COUNT(*) FROM still_active) AS REAL) / NULLIF((SELECT COUNT(*) FROM prev_active), 0)), 1) AS churn_pct;

Важнее самого числа — тренд и ранние сигналы, которые предшествуют оттоку и которые можно отследить раньше, чем игрок пропадёт совсем:

  • падение частоты заходов у конкретного игрока (был через день, стал раз в неделю) — считается как скользящее среднее интервала между сессиями;
  • сокращение средней длительности сессии;
  • всплеск на форуме/в Discord-тикетах с жалобами на лаг, читеров или конкретный баг перед волной уходов — тут помогает мониторинг статуса сервера, чтобы отличить реальные простои от вкусовых жалоб (см. статью про бота для мониторинга статуса сервера);
  • отток именно «ядра» (топ-20% по часам в сообществе) — это куда тревожнее, чем уход случайных новичков, потому что ядро тянет за собой остальных.

Порог, после которого стоит бить тревогу — не абсолютное число, а перелом тренда: если churn_30d два-три периода подряд растёт быстрее, чем приходит новых игроков, сообщество сжимается, даже если текущий онлайн ещё выглядит нормально.

Сбор данных: логи подключений и боты статистики

Три источника данных, которые реально доступны без переусложнения:

  1. Логи сервера. Практически все движки пишут вход/выход в лог: Minecraft — logs/latest.log (UUID of player X is ... и X joined the game), source-движки (CS2, Rust) — консольный лог с событиями подключения. Их можно парсить регулярным опросом или подпиской на файл (tail -f style) и писать события в свою таблицу.
  2. Query/RCON-опрос по расписанию. Периодический опрос через query-протокол или RCON даёт срезы онлайна, даже если парсинг логов недоступен или неудобен (подробнее про сам механизм — в статье про Server Query API для ботов мониторинга). Плюс подхода — не нужен доступ к файловой системе сервера, минус — не видно точного момента входа/выхода отдельного игрока, только срез «кто сейчас в списке».
  3. Discord-боты категории voice. Если вокруг сервера уже есть Discord-комьюнити, боты статистики онлайна из раздела voice решают сбор и частично визуализацию за вас — не нужно поднимать отдельный дашборд, команда /retention или /stats в Discord-канале закрывает потребность админа заглянуть в цифры без захода в консоль сервера.

Для старта достаточно связки: планировщик (cron/node-cron) → query-опрос раз в 5-15 минут → запись в SQLite → еженедельный SQL-запрос (или Discord-команда) с retention/churn/тепловой картой. Это не требует внешних SaaS-сервисов аналитики и работает даже на минимальном тарифе — вся нагрузка на CPU/RAM от таких запросов пренебрежимо мала на фоне самого игрового процесса, так что отдельно закладывать под это ресурсы сервера не нужно.

Как реагировать на падение метрик

Метрики бесполезны без плана действий на случай, когда они просели. Разберём по типам сигнала:

D1 упал, а D7/D30 стабильны. Проблема в первом впечатлении: сложный спавн, непонятные правила, отсутствие приветственного тикета/гайда. Чинится онбордингом — welcome-сообщением с командами, коротким гайдом на первые 10 минут, автоматической выдачей стартового набора.

D7 упал, а D1 в норме. Игроки заходят один раз с интересом, но не находят причины вернуться на следующей неделе. Обычно не хватает социального крючка — гильдий/кланов, регулярных ивентов, экономики, которая требует возвращаться (аренда участка, налоги, аукцион). Помогает регулярный, предсказуемый календарь ивентов, который анонсируется заранее в те самые пиковые часы из тепловой карты.

Резкий провал онлайна в конкретный день без видимой причины. Первым делом — проверить аптайм и лог ошибок за этот период, а не сразу винить контент: технический сбой (краш, дюп-баг, читер-волна) выбивает ядро сообщества быстрее любого другого фактора. Автоматический мониторинг статуса и алерты в Discord сокращают время реакции с «узнали от игроков утром» до «узнали через 5 минут после падения».

Постепенное сжатие ядра при стабильном притоке новичков. Это самый опасный сценарий — сервер выглядит живым по онлайну, но постоянные игроки уходят, а их место занимают новички с низким D7. Обычно причина в усталости контента (вайп слишком редкий или слишком частый, экономика разбалансирована, гриферы или читеры не банятся достаточно быстро) — здесь метрики только показывают симптом, лечение требует разбора конкретно вашей конфигурации сервера и модерации.

Общее правило: смотреть не на одну точку, а на тренд минимум за 3-4 периода (недели для D7, месяцы для D30) — единичный провал онлайна легко объясняется внешним фактором (крупный релиз конкурирующей игры, праздники, банальный даунтайм провайдера), а вот устойчивое падение по двум-трём метрикам подряд — уже сигнал разбираться предметно.

Нужен игровой сервер?

MAATRIX GAMES — 45+ игр, деплой за минуты, DDoS-защита, автобэкапы. Тарифы от 399 ₽/мес.

Создать сервер

Частые вопросы

Нужна ли для этого отдельная база данных или платный сервис аналитики?

Нет, для сервера на несколько сотен уникальных игроков в месяц хватает SQLite-файла и пары cron-задач — это укладывается в те же ресурсы, где крутится Discord-бот, отдельная инфраструктура не нужна.

Как отличить реального игрока от алкоголика-бота или мультиаккаунта в подсчёте retention?

Простого универсального решения нет: минимальный фильтр — отсекать сессии короче 1-2 минут и учитывать по UUID/SteamID, а не по IP, плюс сверяться со списком известных читер-инструментов/впн-диапазонов, если проблема массовая.

Что делать, если логов подключений за прошлые месяцы не сохранилось?

Начать копить с сегодняшнего дня — retention и churn считаются по когортам с момента старта сбора, задним числом эти цифры не восстановить, но уже через 4-6 недель появится первая полезная картина.

Стоит ли считать retention отдельно для каждой локации сервера (UK/US/RU), если аудитория интернациональная?

Да, если аудитория заметно смешанная — иначе тепловая карта по часам получится смазанной, а решения по времени рестарта/ивентов будут ошибочными для одной из групп.

Как часто пересчитывать метрики?

Retention и churn — раз в неделю достаточно (это медленные метрики), тепловую карту онлайна по часам — можно обновлять раз в сутки, лишней нагрузки это не создаёт.