Бран · продюсер «Хроник Пограничья»
В начале апреля время в игре на игрока подскочило в полтора раза! Это наш весенний ивент так зашёл? И заодно скажи, сколько у нас вообще народу каждый день и насколько игра «липкая».
В прошлом уроке мы нашли, где новички теряются. Теперь смотрим на всех игроков сразу: сколько их в игре каждый день и каждый месяц. Определения мы дали ещё в уроке про метрики: DAU это число уникальных игроков с хотя бы одной сессией за день, MAU то же за месяц, WAU за неделю.
Посетители кафе и постоянные гости
Кафе может считать посетителей за день и за месяц. Если за месяц пришли 1000 разных людей, а в обычный день заходят 160, то средний гость бывает примерно пять дней из тридцати. Отношение «день к месяцу» говорит, насколько кафе стало привычкой.
В играх это отношение называют stickiness, липкость: средний DAU за месяц, делённый на MAU этого месяца.
DAU, WAU, MAU одним шаблоном
Все три метрики это «сколько разных игроков за период», меняется только округление даты:
SELECT started_at::date AS day,
count(DISTINCT player_id) AS dau
FROM sessions
GROUP BY day
ORDER BY day;
Для WAU берём date_trunc('week', started_at)::date, для MAU date_trunc('month', started_at)::date. Главное здесь DISTINCT: игрок с пятью сессиями за день это один активный игрок, а не пять.
Ловим ботов
Вернёмся к вопросу Брана про время в игре. Посчитаем по неделям часы на одного активного игрока:
SELECT date_trunc('week', started_at)::date AS week,
count(DISTINCT player_id) AS wau,
round(sum(extract(epoch FROM ended_at - started_at)) / 3600
/ count(DISTINCT player_id), 2) AS hours_per_user
FROM sessions
WHERE started_at >= '2026-03-23' AND started_at < '2026-04-27'
GROUP BY week
ORDER BY week;
week | wau | hours_per_user
------------+-----+----------------
2026-03-23 | 478 | 1.95
2026-03-30 | 467 | 2.36
2026-04-06 | 462 | 3.37
2026-04-13 | 463 | 2.19
2026-04-20 | 476 | 2.02
Число игроков не изменилось, а часы выросли в полтора раза и через неделю вернулись к прежним. Так ивенты не работают: от ивента растёт и число игроков. Посмотрим на самые длинные сессии:
SELECT p.id, p.nickname,
count(*) AS long_sessions,
max(s.ended_at - s.started_at) AS longest
FROM sessions s
JOIN players p ON p.id = s.player_id
WHERE s.ended_at - s.started_at > interval '12 hours'
GROUP BY p.id, p.nickname
ORDER BY long_sessions DESC, p.id;
id | nickname | long_sessions | longest
------+----------+---------------+----------
2002 | farm632x | 10 | 23:58:02
2021 | farm619x | 10 | 23:55:55
2040 | farm463x | 10 | 23:54:29
2070 | farm239x | 10 | 23:55:19
2072 | GHOST18 | 1 | 13:27:36
Четыре аккаунта farm…x десять дней подряд сидят в игре почти сутки без перерыва. Это бот-ферма. Человек так не играет. А вот GHOST18 с одной сессией на 13,5 часа похож на живого человека в выходной марафон: одна длинная сессия ещё не делает игрока ботом.
Поэтому порог берём строже: бот это аккаунт, у которого была сессия длиннее 20 часов. Вместе с тестовыми аккаунтами студии это список «не настоящих игроков», вынесем его в CTE.
урок из курса
Урок из курса «Аналитика данных с нуля». Курс покупается один раз и остаётся навсегда: 500 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.