Перейти к содержимому
AI Agent

Install with AI Agent

Copy & paste this prompt

Install the Hyperstone Unity SDK in this project. Follow these steps: 1. Read the integration recipe: https://hyperstone.ai/docs/llms.txt 2. Use the documentation that best fits your context window: - Minimal (fast): https://hyperstone.ai/docs/llms.txt - Full (comprehensive): https://hyperstone.ai/docs/llms-full.txt - Small (optimized): https://hyperstone.ai/docs/llms-small.txt 3. Execute the installation following the recipe instructions. 4. Verify that the SDK is correctly installed and integrated into the project.

Интеграция

using UnityEngine;
using HyperstoneSdk;
public class MyGame : MonoBehaviour
{
void Start()
{
// Подписываемся на изменения конфигурации — можно вызвать до Initialize
Hyperstone.WatchConfig(OnConfigChanged);
// Инициализируем с использованием учетных данных из Консоли Hyperstone
Hyperstone.Initialize("YOUR_APP_ID", "YOUR_APP_SECRET");
}
void OnConfigChanged(HyperstoneConfig config)
{
// Читаем оптимизированные значения, отправленные Hyperstone
int lives = config.GetIntOrDefault("n_lives", 3);
bool showAdsAfterDeath = config.GetBoolOrDefault("show_ads_after_death", true);
// Применяем к логике вашей игры
GameManager.Instance.SetLives(lives);
GameManager.Instance.SetAdsAfterDeath(showAdsAfterDeath);
}
void OnDestroy()
{
Hyperstone.UnwatchConfig(OnConfigChanged);
}
}

Вот и всё. Hyperstone автоматически будет:

  1. Получать оптимизированную конфигурацию, адаптированную для этого пользователя
  2. Передавать её в ваш callback
  3. Отслеживать метрики сессии (количество сессий, время вовлеченности, retention)
  4. Отправлять накопленные метрики на бэкенд Hyperstone

Вызовите Hyperstone.Initialize() один раз при запуске вашего приложения (обычно в MonoBehaviour.Start() или в bootstrap-скрипте):

Hyperstone.Initialize("YOUR_APP_ID", "YOUR_APP_SECRET");
ПараметрТипОписание
appIdstringВаш Application ID из Консоли Hyperstone.
appSecretstringВаш Application Secret из Консоли Hyperstone.
logLevelHyperstoneClient.LogLevel(Опционально) Уровень детализации логов. По умолчанию: LogLevel.Info.

Вы можете найти свой App ID и App Secret в Консоли Hyperstone.

Initialize должен быть вызван только один раз. Последующие вызовы будут игнорироваться с предупреждением в логах.

Подписка на изменения конфигурации

Section titled “Подписка на изменения конфигурации”

Используйте Hyperstone.WatchConfig(), чтобы получать обновления конфигурации. Вы можете подписаться в любой момент в вашем проекте — даже до вызова Initialize. Это особенно полезно для разделенных архитектур, где разные системы регистрируют свой интерес к конфигурации независимо.

// Подписываемся заранее — даже до Initialize
Hyperstone.WatchConfig(OnConfigChanged);
void OnConfigChanged(HyperstoneConfig config)
{
// Этот метод вызывается:
// 1. Немедленно с кэшированной конфигурацией (если она существует)
// 2. Снова, когда с сервера приходит свежая конфигурация
}

При подписке:

  • Если конфигурация уже доступна (закэширована из предыдущей сессии или получена с сервера), ваш callback сработает немедленно с текущей конфигурацией.
  • Когда с сервера будет получена свежая конфигурация, все зарегистрированные callback-функции сработают снова с новой конфигурацией.

Для отписки:

Hyperstone.UnwatchConfig(OnConfigChanged);

Чтение значений конфигурации

Section titled “Чтение значений конфигурации”

HyperstoneConfig предоставляет типизированные методы доступа с возможностью указания значения по умолчанию (fallback). Ключи конфигурации и их типы значений определяются вами в Консоли Hyperstone при настройке параметров оптимизации.

void OnConfigChanged(HyperstoneConfig config)
{
// Примитивы с безопасными значениями по умолчанию
int lives = config.GetIntOrDefault("n_lives", 3);
float speed = config.GetFloatOrDefault("player_speed", 5.0f);
double ratio = config.GetDoubleOrDefault("reward_ratio", 1.5);
long bigNum = config.GetLongOrDefault("score_cap", 1000000L);
bool showAds = config.GetBoolOrDefault("show_ads_after_death", true);
string theme = config.GetStringOrDefault("ui_theme", "dark");
// Паттерн TryGet (возвращает false, если ключ отсутствует или тип не совпадает)
if (config.TryGetInt("bonus_level", out int bonus))
{
// Используем bonus
}
}

Для получения полного списка методов доступа обратитесь к API Reference.

Десериализация конфигурации в объект

Section titled “Десериализация конфигурации в объект”

Если ваша конфигурация четко соответствует C#-классу, вы можете десериализовать её одним вызовом с помощью JsonUtility от Unity:

[Serializable]
public class GameConfig
{
public int n_lives;
public bool show_ads_after_death;
public float player_speed;
}
void OnConfigChanged(HyperstoneConfig config)
{
GameConfig gameConfig = config.AsObject<GameConfig>();
// или обновить существующий экземпляр:
// config.OverwriteObject(existingGameConfig);
}

Hyperstone должен знать, что происходит в вашем приложении, чтобы оптимизировать конфигурацию. SDK предоставляет методы для отслеживания стандартных событий (реклама, внутриигровые покупки) и кастомных событий/метрик.

Автоматически собираемые данные

Section titled “Автоматически собираемые данные”

Некоторые события и свойства отслеживаются SDK автоматически и не требуют написания кода.

Свойства устройства пользователя

  • Версия SDK, версия Unity и платформа
  • Bundle ID приложения и числовая версия
  • Операционная система, модель устройства и тип устройства (Телефон/Планшет)
  • Код языка и часовой пояс
  • Флаг режима разработчика

Системные метрики

  • Сессии и время — общее время вовлеченности (в минутах) и общее количество сессий. Новые сессии начинаются при запуске приложения или при возврате из паузы после тайм-аута.
  • Retention и стрики — общее количество разных дней игры, непрерывные серии заходов (streaks) и отслеживание календарных дней.
  • Агрегированный доход — общий общий доход, общий рекламный доход/запросы/показы/ошибки и агрегированные итоги IAP.
  • Конверсии — события конверсии в платящего пользователя (первая покупка игрока).
// Пользователь увидел рекламу — укажите доход для ILRD
Hyperstone.LogAdImpression(
adPlatform: "admob", // Медиационная платформа (например, "admob", "ironsource", "max")
adNetwork: "meta", // Рекламная сеть, которая показала рекламу
adFormat: "rewarded", // Формат рекламы ("banner", "interstitial", "rewarded", "native")
revenueUsd: 0.0032 // Оценочный доход в USD
);
// Запрос рекламы
Hyperstone.LogAdRequest(
adPlatform: "admob",
adFormat: "interstitial"
);
// Ошибка загрузки/показа рекламы
Hyperstone.LogAdError(
adPlatform: "admob",
adNetwork: "meta",
adFormat: "interstitial",
failReason: "no_fill" // Опционально, по умолчанию "unknown"
);

События внутриигровых покупок (IAP)

Section titled “События внутриигровых покупок (IAP)”

Вы можете измерять доход от внутриигровых покупок с помощью метода LogIapTransactionSuccess. Вы должны вручную передать локализованную цену, чтобы правильно измерить сгенерированный доход:

// Успешная покупка
Hyperstone.LogIapTransactionSuccess(
productId: "gems_100",
currency: "USD",
price: 4.99 // Цена будет отслеживаться как IAP-доход для расчета LTV
);
// Ошибка покупки
Hyperstone.LogIapTransactionError(
productId: "gems_100",
failReason: "cancelled"
);

SDK автоматически обнаруживает первую успешную покупку и сообщает о событии конверсии в плательщика. Последующий рекламный доход для платящих пользователей дополнительно отслеживается как отдельное измерение.

Кастомные события и метрики

Section titled “Кастомные события и метрики”

Для отслеживания специфичных для приложения данных используйте кастомные события и метрики:

// Простое событие (считается со значением = 1)
Hyperstone.LogCustomEvent("level_completed");
// Событие с лейблами для сегментации
Hyperstone.LogCustomEvent("level_completed",
new Label("difficulty", "hard"),
new Label("world", "forest")
);
// Числовая метрика (суммирует значение)
Hyperstone.IncrementCustomMetric("coins_spent", 50);
// Числовая метрика с лейблами
Hyperstone.IncrementCustomMetric("damage_dealt", 127.5f,
new Label("weapon", "sword"),
new Label("enemy_type", "boss")
);

Правила именования кастомных метрик:

  • Только буквенно-цифровые символы, дефисы и подчеркивания ([a-zA-Z0-9-_])
  • Максимум 100 символов

Лейблы (Labels) прикрепляют метаданные с низкой кардинальностью к измерениям. Сервис Hyperstone использует лейблы для сегментации и агрегации данных. Хорошими кандидатами для лейблов являются такие вещи, как рекламные сети, уровни сложности или категории предметов, но не уникальные ID пользователей или временные метки.

Примеры ILRD (Impression-Level Revenue Data)

Section titled “Примеры ILRD (Impression-Level Revenue Data)”

Данные о доходе на уровне показов (ILRD) критически важны для оптимизации рекламного дохода. Вот как интегрировать их с популярными платформами медиации.

using GoogleMobileAds.Api;
// При настройке rewarded ad:
rewardedAd.OnAdPaid += (AdValue adValue) =>
{
// AdMob сообщает стоимость в микроединицах (1,000,000 микро = 1 единица валюты)
double revenueUsd = adValue.Value / 1_000_000.0;
Hyperstone.LogAdImpression(
adPlatform: "admob",
adNetwork: "admob", // AdMob как сеть, когда не используется медиация
adFormat: "rewarded",
revenueUsd: revenueUsd
);
};
// Для медиированных объявлений извлекайте название фактической рекламной сети из имени класса адаптера или информации об ответе:
rewardedAd.OnAdPaid += (AdValue adValue) =>
{
double revenueUsd = adValue.Value / 1_000_000.0;
var responseInfo = rewardedAd.GetResponseInfo();
var loadedAdapterName = responseInfo?.GetLoadedAdapterResponseInfo()?.AdSourceName ?? "unknown";
Hyperstone.LogAdImpression(
adPlatform: "admob",
adNetwork: loadedAdapterName,
adFormat: "rewarded",
revenueUsd: revenueUsd
);
};
using Unity.Services.LevelPlay;
// Подписываемся на событие данных о показах
IronSourceEvents.onImpressionDataReadyEvent += OnImpressionDataReady;
void OnImpressionDataReady(IronSourceImpressionData impressionData)
{
if (impressionData.revenue.HasValue)
{
Hyperstone.LogAdImpression(
adPlatform: "ironsource",
adNetwork: impressionData.adNetwork ?? "unknown",
adFormat: impressionData.adUnit ?? "unknown",
revenueUsd: impressionData.revenue.Value
);
}
}

Управление данными и утилиты

Section titled “Управление данными и утилиты”

Очистка пользовательских данных

Section titled “Очистка пользовательских данных”

Чтобы сбросить все локально сохраненные данные Hyperstone (например, при выходе пользователя из аккаунта или когда вам нужен «чистый лист»):

Hyperstone.ClearData();

Это удаляет сохраненный UID, закэшированную конфигурацию, накопленные метрики, историю сессий и статус плательщика. Следующий вызов Initialize будет воспринимать этого пользователя как совершенно нового.

Управляйте уровнем детализации логов SDK:

Hyperstone.LogLevel = HyperstoneClient.LogLevel.Debug; // Подробно — полезно при разработке
Hyperstone.LogLevel = HyperstoneClient.LogLevel.Info; // По умолчанию — инициализация и ключевые события
Hyperstone.LogLevel = HyperstoneClient.LogLevel.Warning; // Только предупреждения и ошибки
Hyperstone.LogLevel = HyperstoneClient.LogLevel.Error; // Только ошибки

Вы также можете передать уровень логов прямо при инициализации:

Hyperstone.Initialize("YOUR_APP_ID", "YOUR_APP_SECRET", HyperstoneClient.LogLevel.Debug);

Все логи SDK начинаются с префикса [Hyperstone]: для удобной фильтрации в консоли Unity.

Понимание внутренних механизмов SDK поможет вам использовать его эффективно и отлаживать проблемы интеграции.

Статический класс Hyperstone является фасадом над синглтоном HyperstoneClient (MonoBehaviour). При первом обращении SDK создает игровой объект [Hyperstone], помеченный DontDestroyOnLoad, чтобы он сохранялся при смене сцен.

sequenceDiagram
    participant App as Ваше приложение
    participant SDK as Hyperstone SDK
    participant Storage as PlayerPrefs
    participant Server as Сервер Hyperstone

    Note over App, Server: Инициализация и получение конфигурации
    App->>SDK: Hyperstone.WatchConfig(callback)
    App->>SDK: Hyperstone.Initialize(appId, appSecret)
    SDK->>Storage: Загрузка закэшированного UID, конфигурации, метрик
    Storage-->>SDK: Кэшированные данные (если есть)
    SDK-->>App: callback(кэшированная конфигурация)

    SDK->>Server: POST /v1/c {свойства пользователя}
    Note right of SDK: Заголовки: xp-app-id, xp-app-secret, xp-uid
    Server-->>SDK: Config JSON + UID
    SDK->>Storage: Сохранение UID + конфигурации
    SDK-->>App: callback(свежая конфигурация)

    Note over App, Server: Отслеживание событий
    App->>SDK: LogAdImpression / LogIap / IncrementCustomMetric
    SDK->>SDK: Накопление в буфере метрик
    SDK->>Storage: Сохранение буфера (защита от вылетов)

    Note over SDK, Server: Отправка метрик (debounced, с кулдауном)
    SDK->>Server: POST /v1/i {пакет метрик}
    Note right of SDK: Заголовки: xp-app-id, xp-app-secret, xp-uid
    alt Успех
        Server-->>SDK: 200 OK
        SDK->>Storage: Очистка отправленных метрик
    else Ошибка
        Server-->>SDK: Error
        SDK->>SDK: Возврат метрик в буфер для повтора
    end

    Note over SDK, Server: Автоматически (без кода)
    loop Каждые 15с, пока приложение активно
        SDK->>SDK: Инкремент времени вовлеченности
    end
    SDK->>SDK: Отслеживание сессий, retention, стриков
  1. ИнициализацияHyperstone.Initialize() создает/находит синглтон, сохраняет ваши учетные данные, загружает из PlayerPrefs любые закэшированные конфигурации и метрики, и начинает запрос на получение конфигурации.
  2. Получение конфигурации — SDK отправляет POST запрос к Hyperstone API с устройствами и свойствами пользователя. Сервер отвечает оптимизированной конфигурацией и уникальным идентификатором пользователя (UID). Оба значения сохраняются локально.
  3. Доставка конфигурации — Как только конфигурация приходит, все зарегистрированные WatchConfig callback-функции вызываются. Если закэшированная конфигурация существовала с предыдущей сессии, callback-функции срабатывают немедленно при подписке, а затем снова, когда приходит свежая конфигурация.
  4. Сбор метрик — События (показы рекламы, покупки, кастомные метрики, сессии, время вовлеченности) накапливаются в буфере в памяти и периодически сохраняются в PlayerPrefs. Это гарантирует, что данные не будут потеряны при вылете приложения.
  5. Отправка метрик — SDK группирует метрики и отправляет их на бэкенд с окном дебаунса (0.5с) и периодом кулдауна (20с), чтобы не перегружать сервер. Если отправка не удалась, метрики возвращаются в буфер и будут отправлены при следующей возможности.
  6. Управление сессиями — SDK автоматически отслеживает сессии, определяя новую сессию при запуске приложения или при возврате из фоновой паузы длительностью более 30 секунд. Время вовлеченности измеряется 15-секундными интервалами. Retention отслеживается как в «мягких днях» (16+ часов между сессиями), так и по календарным дням.

Все данные хранятся в Unity PlayerPrefs под ключами с пространством имен вашего App ID (например, xp-uid-{appId}, xp-config-{appId}). Это означает, что:

  • Конфигурация и метрики сохраняются после перезапуска приложения
  • Метрики, которые не удалось отправить, буферизуются и отправляются повторно
  • Каждое приложение (App ID) имеет изолированное хранилище (актуально для мультитенентности)

Все вызовы статического API Hyperstone потокобезопасны. Вы можете безопасно вызывать Hyperstone.Initialize(), Hyperstone.WatchConfig(), Hyperstone.LogAdImpression() и все остальные методы из любого потока — включая фоновые потоки, async-задачи или коллбэки системы Job System.

Под капотом статический фасад Hyperstone захватывает SynchronizationContext главного потока Unity при запуске (через [RuntimeInitializeOnLoadMethod]). Если вызов производится из не-главного потока, он автоматически перенаправляется в главный поток с помощью SynchronizationContext.Post(). Это гарантирует, что базовый HyperstoneClient (который использует корутины и Unity API) всегда работает в главном потоке, при этом вашему коду не нужно беспокоиться о принадлежности к потоку.

Продвинутое: Мультитенентность (Multi-Tenancy)

Section titled “Продвинутое: Мультитенентность (Multi-Tenancy)”

Статический API Hyperstone управляет одним общим экземпляром клиента (паттерн синглтон). В большинстве приложений этого достаточно.

Однако, если вашему приложению нужно взаимодействовать с несколькими приложениями Hyperstone одновременно (например, платформа публикации, хостящая несколько тайтлов, или одно приложение с разными областями оптимизации), вы можете создавать и управлять экземплярами HyperstoneClient вручную:

using UnityEngine;
using HyperstoneSdk;
public class MultiTenantExample : MonoBehaviour
{
private HyperstoneClient _gameplayClient;
private HyperstoneClient _monetizationClient;
void Start()
{
// Создаем отдельные экземпляры клиентов для разных областей приложения
_gameplayClient = CreateClient("GameplayOptimizer");
_gameplayClient.Initialize("GAMEPLAY_APP_ID", "GAMEPLAY_APP_SECRET");
_gameplayClient.WatchConfig(OnGameplayConfigChanged);
_monetizationClient = CreateClient("MonetizationOptimizer");
_monetizationClient.Initialize("MONETIZATION_APP_ID", "MONETIZATION_APP_SECRET");
_monetizationClient.WatchConfig(OnMonetizationConfigChanged);
}
private HyperstoneClient CreateClient(string name)
{
var go = new GameObject($"[Hyperstone - {name}]");
DontDestroyOnLoad(go);
return go.AddComponent<HyperstoneClient>();
}
void OnGameplayConfigChanged(HyperstoneConfig config)
{
int lives = config.GetIntOrDefault("n_lives", 3);
// ...
}
void OnMonetizationConfigChanged(HyperstoneConfig config)
{
int adCooldown = config.GetIntOrDefault("ad_cooldown_seconds", 60);
// ...
}
}