Перейти до основного вмісту
Сервіси навколо гри

Цю сторінку ще не перекладено — показано англійську версію.

Analytics

Усе, що треба порахувати потім, а не побачити зараз. Оголосіть типізовану подію телеметрії, надішліть її — і вона ляже поруч із подіями самої платформи: пройдений рівень, крок воронки, економічна подія, тривалість сесії, відвал на навчанні. Цей модуль лише надсилає: сам він нічого не читає, не агрегує й нікуди не доставляє. Куди піде пакет подій, вирішує маршрутизатор у Extensibility.

Коли це потрібно

  • Щось треба порахувати потім: крок воронки, пройдений рівень, економічну подію, тривалість сесії.
  • Порівняння має переживати нові збірки гри: тип несе версію схеми (schema), тож воронка, якій уже рік, не змішує мовчки два значення одного поля.
  • Обсяг великий, і втрата рядка прийнятна, якщо ви так оголосили: телеметрія — єдине місце в контракті, де оголошена втрата законна.
  • Не знадобиться, якщо хтось має відреагувати. У події (event) телеметрії взагалі немає підписників, а факт, про який мають дізнатися інші, — це ігрова подія.

Хто що робить

АкторМожеНе може
будь-який актороголошувати типи в схемі; надсилати події від власного імені — по одній або пакетом (batch); читати оголошені типизаповнювати контекст; читати, запитувати чи агрегувати надіслане
backend-serviceте саме, а також надсилати події від імені гравця через делегуваннячитати телеметрію: дозволу на читання немає, бо немає й операції читання

Коротко

Оголошення й надсилання BossDefeated: іменовані типізовані поля замість JSON-блоба
[Event("boss_defeated")]
public class BossDefeated
{
    public string BossId = "";
    public int PartySize;
    public float FightSeconds;
}

PlayServ.Analytics.Emit(new BossDefeated { BossId = "hydra", PartySize = 4, FightSeconds = 212f });
@Event('boss_defeated')
export class BossDefeated {
  bossId = '';
  partySize = 0;
  fightSeconds = 0;
}

PlayServ.analytics.emit(new BossDefeated({ bossId: 'hydra', partySize: 4, fightSeconds: 212 }));
@event("boss_defeated")
class BossDefeated:
    boss_id: str = ""
    party_size: int = 0
    fight_seconds: float = 0.0

playserv.analytics.emit(BossDefeated(boss_id="hydra", party_size=4, fight_seconds=212.0))
Незабаром — Go

Як оголошувати через атрибути в Go, поки не вирішено (O-1). Приклади з’являться, коли оберуть спосіб запису.

USTRUCT(PSEvent = (Name = "boss_defeated"))
struct FBossDefeated
{
    GENERATED_BODY()

    UPROPERTY() FString BossId;
    UPROPERTY() int32   PartySize;
    UPROPERTY() float   FightSeconds;
};
// declarations compile into the same pushed model — playserv push from the UE project or CI

// the declared type becomes a generated member under the Emit node
Client->Analytics->Emit->BossDefeated({ TEXT("hydra"), /*PartySize*/ 4, /*FightSeconds*/ 212.f });
// co_await support ships later: a built-in SDK coroutine wrapper that respects Unreal's GC and threading.
Unity C# is the same C# API here — те саме оголошення й виклик Emit компілюються в Unity на базовій версії 2021.3
[Event("boss_defeated")]
public class BossDefeated
{
    public string BossId = "";
    public int PartySize;
    public float FightSeconds;
}

PlayServ.Analytics.Emit(new BossDefeated { BossId = "hydra", PartySize = 4, FightSeconds = 212f });

Визначення — це схема, тож те, що надходить, має іменовані типізовані поля, а не JSON-блоб. Його оголошують як окремий вид, а не як ігрову подію з прапорцем.

Модель

Що оголошує тип події телеметрії.

ОголошенняЩо це
nameвласне ім’я типу
fieldsтипізовані системою типів платформи; маска полів (field mask) застосовується до них так само, як і скрізь
версія схемиобов’язкова й не виводиться з версії SDK. Воронка порівнює події, зібрані в різних збірках гри, і без версії таке порівняння мовчки змішує непорівнюване
samplingяка частка подій цього типу проходить далі. Семплювання оголошують на типі, а реалізація ніколи не обирає його сама залежно від навантаження: якби частка змінювалася сама собою, воронки за різні дні стали б непорівнюваними
допустимість втратчи допускає цей тип втрати
поведінка під час видаленняяк видалення гравця позначається на цьому типі — видаленням або анонімізацією. Політику оголошує студія, а виконує модуль

Що справджується для кожної події телеметрії.

ЗавждиЩо це
немає адресатані отримувача, ні групи, ні підписки. Якщо хочеться когось адресувати, це ознака, що потрібна ігрова подія
контекстналежить платформі: вона додає актора або позначку анонімності, сесію, середовище, версію збірки й момент за оголошеним годинником. Викликач не може його заповнити: якщо він підставить актора чи версію збірки, платформа все одно запише власні значення замість переданих
частка семплюванняпередається разом із подією: без неї абсолютне число не відновити з того, що надійшло
втратапомітна в сукупності: частка недоставленого за період доступна споживачеві. Помітності кожної окремої втрати не обіцяють, бо за обсягів телеметрії повідомлення про кожну втрату саме стало б потоком даних
надсиланняне ідемпотентне: два виклики — це два факти, і ключа ідемпотентності воно не приймає, бо придушення другого виклику втратило б дані. Дізнатися результат загубленого надсилання неможливо, і це й не потрібно: допустимість втрат оголошують заздалегідь, одразу для всіх викликів
подіїі є історією: власної модуль не зберігає

Помилки

  • Неоголошений тип і поле, що не відповідає схемі типу, — це відмови валідації. Жодна з них не стане несподіванкою під час виконання, бо тип потрапляє в адмін-консоль зі свого оголошення.
  • Завелика подія — відмова валідації; поля ніколи мовчки не обрізають.
  • Перевищено частоту — відповідь категорії обмеження частоти з часом, до якого повторювати марно.
  • Відкидання під час семплювання — не помилка, як і допустима втрата. Виклик виконано, а відкидання — оголошена поведінка. Якби про них повідомляли як про збій, оголошену поведінку не можна було б відрізнити від несправності.
  • Пакет обробляють або цілком, або поелементно, і це оголошено — ніколи не «як вийшло».

Обмеження

Конкретні числа з’являться в розділі про ліміти платформи, а що відбувається на кожній межі, визначено вже зараз.

  • Частота подій на актора: відмова через обмеження частоти з указаним терміном. Перевищення частоти ніколи не означає тихого відкидання: це або така відмова, або оголошене відкидання під час семплювання.
  • Розмір однієї події: відмова валідації, а не мовчки обрізані поля.
  • Розмір пакета: пакет відхиляють ще до надсилання, а не застосовують частково.
  • Оголошені типи на проєкт: нове оголошення відхиляють під час деплою, а не під час виконання.
  • Поля в типі: так само, під час деплою.
  • Строк зберігання: після оголошеного строку подія вже недоступна.