# PrimeSDK Documentation Canonical install URL: https://github.com/Prime-SDK/PrimeSDK.git Public repository: https://github.com/Prime-SDK/PrimeSDK.git Version: 5.1.53 Updated: 2026-06-04 ## Russian # PrimeSDK Documentation Документация о назначении PrimeSDK, его возможностях и принципах работы - в формате, удобном как для разработчиков, так и для ИИ-агентов. Version: 5.1.53 Install URL: https://github.com/Prime-SDK/PrimeSDK.git ## Для чего нужен Prime SDK PrimeSDK нужен, чтобы объединить платформенные интеграции Unity-проекта в один управляемый слой. Кроссплатформенный многофункциональный плагин для Unity PrimeSDK помогает упростить разработку и сделать код проекта более чистым и читаемым. Вместо прямой интеграции множества разных плагинов вы можете использовать единый API PrimeSDK. Основная задача PrimeSDK - предоставить универсальный абстрактный интерфейс для ключевых игровых сервисов: рекламы, платежей, аналитики, сохранения данных и других инструментов, которые часто используются в разработке. Вы выбираете нужных провайдеров, подключаете их к PrimeSDK и работаете через единый API. Это позволяет снизить сложность проекта, упростить поддержку кода и быстрее адаптировать игру под разные платформы. PrimeSDK ориентирован на WebGL и платформенные интеграции. Поддержка конкретных функций зависит от выбранной конфигурации, установленных API-пакетов и возможностей самой площадки. > **Важно** > > Полный функционал Prime SDK поддерживается только при условии полной замены существующего API проекта на API Prime SDK. В противном случае часть возможностей SDK может быть недоступна или работать некорректно. Актуальные поддерживаемые интеграции: - PrimeWeb / WebGL - Yandex Games - CrazyGames - GameDistribution - Playgama / Playgama Bridge - Y8 - MSN - Xiaomi - Lagged - Poki - RuStore - Yandex Mobile Ads - Xsolla Web для CrazyGames ## Установка и настройка PrimeSDK устанавливается в Unity через Package Manager по Git URL, после чего проект настраивается через окно PrimeSDK. Перед установкой PrimeSDK убедитесь, что в Unity Console нет ошибок компиляции. Иначе пакет может отображаться некорректно до тех пор, пока все существующие ошибки в проекте не будут исправлены. Также убедитесь, что в проекте не установлены другие версии PrimeSDK, поскольку разные версии SDK могут конфликтовать между собой. Вы можете временно добавить PrimeSDK рядом с предыдущими версиями, если нужно постепенно перенести код проекта. Однако пока в проекте одновременно установлено несколько версий SDK, он может работать некорректно. Если после сборки проекта с PrimeSDK под WebGL у вас появляются критические ошибки вроде `SDK is initialized multiple times` или `SDK instance already exists`, проверьте, что в проекте нет конфликтующего WebGL-нативного кода. Например, `.jslib` или `.jspre` библиотек от других плагинов, которые напрямую взаимодействуют с API WebGL-платформ. Чтобы добавить пакет в проект, откройте Unity Package Manager, выберите `Add package from git URL...` и укажите ```https://github.com/Prime-SDK/PrimeSDK.git``` ## Инициализация К PrimeSDK можно обращаться только после того, как SDK создан и все асинхронные провайдеры выбранной конфигурации готовы к работе. К PrimeSDK можно обращаться только после того, как убедитесь, что он инициализирован и готов к работе. До этого любое обращение к его интерфейсам может привести к исключению, критической ошибке или вылету. В актуальном API PrimeSDK нет публичного свойства `IsInitialized`. Вместо прямой проверки свойства готовности используйте `PrimeSDK.WaitForProviders(...)`. Этот метод вызывает callback, когда все компоненты выбранной конфигурации, которым требуется асинхронная загрузка, готовы к работе. Перед ожиданием провайдеров нужно создать экземпляр SDK: `csharp using PrimeGames.SDK; PrimeSDK.CreateInstance(); ` Пример 1. Используя корутину: `csharp using System.Collections; using PrimeGames.SDK; using UnityEngine; public IEnumerator WaitForPrimeSDK() { bool isReady = false; PrimeSDK.WaitForProviders(() => { isReady = true; }); yield return new WaitUntil(() => isReady); // PrimeSDK готов к работе. } ` Пример 2. Используя callback: `csharp PrimeSDK.WaitForProviders(() => { // PrimeSDK готов к работе. }); ` ## Рекламная монетизация PrimeSDK предоставляет единый API для баннерной, межстраничной и rewarded-рекламы через PrimeSDK.Ads. Перед обращением к рекламе дождитесь готовности SDK через `PrimeSDK.WaitForProviders(...)`. В текущем API нет общего свойства `PrimeSDK.Ads.IsAvailable`; доступность проверяется отдельно по каждому типу рекламы. `csharp bool isAnyAdsAvailable = PrimeSDK.Ads.IsBannerAvailable || PrimeSDK.Ads.IsInterstitialAvailable || PrimeSDK.Ads.IsRewardedAvailable; ` Баннерная реклама > **Важно** > > Баннерная реклама поддерживается не всеми платформами. Актуальность поддержки баннерной рекламы уточняйте в официальной документации платформ, на которых планируете выпускать свой контент. `csharp bool isBannerReady = PrimeSDK.Ads.IsBannerReady; bool isBannerVisible = PrimeSDK.Ads.IsBannerVisible; bool isBannerAvailable = PrimeSDK.Ads.IsBannerAvailable; if (isBannerAvailable && isBannerReady) { PrimeSDK.Ads.InvokeBanner(); } ` Управление баннером: `csharp PrimeSDK.Ads.InvokeBanner(); // показать баннер PrimeSDK.Ads.RefreshBanner(); // обновить содержимое баннера PrimeSDK.Ads.DisableBanner(); // скрыть баннер ` Межстраничная реклама `csharp bool isInterstitialReady = PrimeSDK.Ads.IsInterstitialReady; bool isInterstitialVisible = PrimeSDK.Ads.IsInterstitialVisible; bool isInterstitialAvailable = PrimeSDK.Ads.IsInterstitialAvailable; ` Время последнего успешного закрытия межстраничной рекламы возвращается через `GetLastInterstitialSuccess()`. Если реклама еще ни разу не была успешно закрыта за текущую сессию, метод вернет `null`. `csharp DateTime? lastInterstitialSuccess = PrimeSDK.Ads.GetLastInterstitialSuccess(); if (lastInterstitialSuccess.HasValue) { Debug.Log($"Последний раз межстраничная реклама была закрыта: {lastInterstitialSuccess.Value}"); TimeSpan timeSinceSuccess = DateTime.Now - lastInterstitialSuccess.Value; Debug.Log($"Прошло {timeSinceSuccess.TotalSeconds} секунд с момента последнего закрытия межстраничной рекламы"); } else { Debug.Log("Межстраничная реклама еще не была успешно закрыта за игровую сессию"); } ` Показ межстраничной рекламы: `csharp PrimeSDK.Ads.InvokeInterstitial( onOpen: () => Debug.Log("Межстраничная реклама открыта"), onClose: isSuccess => Debug.Log($"Межстраничная реклама закрыта. Успешно: {isSuccess}"), onAdBlockDetected: () => Debug.Log("AdBlock обнаружен перед показом межстраничной рекламы") ); ` Реклама за вознаграждение `csharp bool isRewardedReady = PrimeSDK.Ads.IsRewardedReady; bool isRewardedVisible = PrimeSDK.Ads.IsRewardedVisible; bool isRewardedAvailable = PrimeSDK.Ads.IsRewardedAvailable; ` `GetLastRewardedSuccess()` можно вызвать без тега, чтобы получить время последнего успешного закрытия любой rewarded-рекламы, или с тегом, чтобы проверить конкретное размещение. Если успешного закрытия еще не было, метод вернет `null`. `csharp DateTime? lastRewardedSuccess = PrimeSDK.Ads.GetLastRewardedSuccess("extra_lives"); if (lastRewardedSuccess.HasValue) { Debug.Log($"Последний раз rewarded-реклама extra_lives была закрыта: {lastRewardedSuccess.Value}"); TimeSpan timeSinceSuccess = DateTime.Now - lastRewardedSuccess.Value; Debug.Log($"Прошло {timeSinceSuccess.TotalSeconds} секунд с момента последнего закрытия extra_lives"); } else { Debug.Log("Rewarded-реклама extra_lives еще не была успешно закрыта за игровую сессию"); } ` Показ rewarded-рекламы. В актуальном API нет отдельного `onSuccess`; результат выдачи награды приходит в `onClose(bool isSuccess)`. `csharp PrimeSDK.Ads.InvokeRewarded( onOpen: () => Debug.Log("Реклама за вознаграждение открыта"), onClose: isSuccess => { Debug.Log($"Реклама за вознаграждение закрыта. Награда выдана: {isSuccess}"); if (isSuccess) { // Выдать награду игроку. } }, rewardTag: "extra_lives", onAdBlockDetected: () => Debug.Log("AdBlock обнаружен перед показом rewarded-рекламы") ); ` Проверка AdBlock Для межстраничной и rewarded-рекламы можно передать `onAdBlockDetected`. SDK проверяет AdBlock только в момент вызова рекламы. Если блокировщик обнаружен, рекламный провайдер не вызывается: сначала срабатывает `onAdBlockDetected`, затем показ завершается через `onClose(false)`. Проверку можно отключить в настройках Ads Provider через параметр `AdBlock Detection Enabled`. Настройка относится к WebGL/PrimeWeb Ads Provider и не запускает постоянную фоновую проверку. > **Важно для CrazyGames** > > Для платформы CrazyGames рекомендуем вызывать в `onAdBlockDetected` стилизованное модальное окно `PrimeSDK.Pause.ShowContinuePrompt()`, так как площадка использует нативный оверлей с уведомлением об активном AdBlock. После закрытия этого оверлея игровое окно теряет фокус, SDK ставит игру на паузу, и для игрока такое состояние выглядит как зависание, что часто приводит к замечаниям со стороны модерации площадки. ## Игровые события PrimeSDK поддерживает базовые игровые события, которые платформы используют для понимания текущего состояния игры. Перед отправкой игровых событий дождитесь готовности SDK через `PrimeSDK.WaitForProviders(...)`. В актуальном API нет свойства `PrimeSDK.Analytics.IsGameplayReporterAvailable`, поэтому проверка доступности игрового репортера через bool-свойство не используется. События этого раздела относятся к состоянию игрового процесса. Отправку произвольных аналитических событий через `Report(...)` сейчас не описываем, потому что backend аналитики еще не поднят. Модальное окно продолжения `PrimeSDK.Pause.ShowContinuePrompt(...)` показывает стилизованное полноэкранное окно с текстом «Чтобы продолжить, кликни по этой области.». Окно вызывается только вручную через API, само не ставит игру на паузу и скрывается после клика по области. Метод принимает необязательный callback `onContinue`, который вызывается после закрытия окна. Это удобно использовать после внешних оверлеев или сценариев, где игроку нужно явно вернуть фокус в игру. `csharp PrimeSDK.Pause.ShowContinuePrompt(() => { Debug.Log("Игрок продолжил игру"); }); ` Событие Game Ready нужно вызывать ровно в момент, когда завершена загрузка всех прогресс-баров, логотипов движка и других стартовых экранов. Проект должен быть готов к взаимодействию. Если на экране отображается сюжетный текст, обучение или другой экран, который блокирует управление, вызывайте Game Ready только после его завершения, когда игрок уже может нажимать на интерактивные элементы. `csharp PrimeSDK.Analytics.GameIsReady(); ` Событие начала игрового процесса отправляется, когда геймплей перешел в активное состояние: игрок непосредственно играет, не находится в главном меню и игра не на паузе. `csharp PrimeSDK.Analytics.GameplayStart(); ` Событие перезапуска игрового процесса отправляется, когда игрок начал игру заново, например после проигрыша или перезапуска уровня. `csharp PrimeSDK.Analytics.GameplayRestart(); ` Событие остановки игрового процесса отправляется, когда геймплей перешел в пассивное состояние: игрок фактически не играет, находится в меню, на паузе или покинул активный игровой цикл. `csharp PrimeSDK.Analytics.GameplayStop(); ` Минимальный пример жизненного цикла: `csharp using PrimeGames.SDK; using UnityEngine; public sealed class GameplayEventsExample : MonoBehaviour { private void Start() { PrimeSDK.WaitForProviders(() => { PrimeSDK.Analytics.GameIsReady(); }); } public void StartGameplay() { PrimeSDK.Analytics.GameplayStart(); } public void RestartGameplay() { PrimeSDK.Analytics.GameplayRestart(); } public void StopGameplay() { PrimeSDK.Analytics.GameplayStop(); } } ` ## Достижения PrimeSDK предоставляет API для спецэффекта Happy Time, достижений и лидербордов через PrimeSDK.Achievements. Перед использованием достижений дождитесь готовности SDK через `PrimeSDK.WaitForProviders(...)`. Поддержка конкретных методов зависит от площадки: если площадка не поддерживает функцию, провайдер может ничего не сделать или вывести предупреждение в лог. `HappyTime()` актуален для CrazyGames и вызывает платформенный спецэффект Happy Time. `csharp PrimeSDK.Achievements.HappyTime(); ` `Unlock(...)` актуален для Lagged и разблокирует достижение по идентификатору. `csharp PrimeSDK.Achievements.Unlock("achievement_id"); ` Получение и сохранение рекорда игрока в лидерборде работает только если игрок авторизован, а площадка поддерживает лидерборды. > **Важно** > > Prime SDK не предоставляет собственные лидерборды. SDK лишь обращается к API платформ, которые поддерживают данный функционал. Если лидерборды отсутствуют на выбранной платформе, соответствующий метод вернет ошибку. Актуальную информацию о поддержке лидербордов уточняйте в официальной документации платформ, на которых планируете размещать свой контент. Получить рекорд игрока в лидерборде: `csharp PrimeSDK.Achievements.GetScore("leaderboard_id", score => { Debug.Log($"Рекорд игрока: {score}"); }); ` Сохранить рекорд игрока в лидерборде: `csharp PrimeSDK.Achievements.SetScore("leaderboard_id", 100); ` Массив игроков в лидерборде может содержать от 0 до 50 элементов. В текущем API `Leaderboard.players` содержит элементы типа `PlayerScore` с полями `displayName`, `position`, `score`, `profilePictureUrl`. Получить лидерборд с массивом игроков: `csharp using PrimeGames.SDK.Common; using UnityEngine; PrimeSDK.Achievements.GetLeaderboard("leaderboard_id", leaderboard => { PlayerScore[] players = leaderboard?.players ?? System.Array.Empty(); Debug.Log($"Получено {players.Length} игроков в лидерборде leaderboard_id"); foreach (PlayerScore player in players) { string displayName = player.displayName; int position = player.position; int score = player.score; string profilePictureUrl = player.profilePictureUrl; Debug.Log($"#{position} {displayName}: {score} ({profilePictureUrl})"); } }); ` ## Сохранение прогресса PrimeSDK.Data хранит прогресс игрока и предоставляет методы для bool, int, float, string и сериализуемых объектов. Перед работой с сохранениями дождитесь готовности SDK через `PrimeSDK.WaitForProviders(...)`. У всех Get-методов есть необязательный параметр `defaultValue`, который используется, если значение по ключу не найдено. Например, `PrimeSDK.Data.GetInt("key", 100)` вернет `100`, если ключ не найден. У всех Set-методов есть необязательный параметр `important`, который по умолчанию равен `true`. Если указать `important: false`, метод изменит значение в памяти, но не вызовет автоматическое сохранение прогресса. После серии таких изменений можно вручную вызвать `PrimeSDK.Data.Save()`. Получить и сохранить bool-значение: `csharp bool value = PrimeSDK.Data.GetBool("key", defaultValue: false); PrimeSDK.Data.SetBool("key", true); ` Получить и сохранить int-значение: `csharp int value = PrimeSDK.Data.GetInt("key", defaultValue: 100); PrimeSDK.Data.SetInt("key", 512); ` Получить и сохранить float-значение: `csharp float value = PrimeSDK.Data.GetFloat("key", defaultValue: 0.0f); PrimeSDK.Data.SetFloat("key", 3.14f); ` Получить и сохранить string-значение: `csharp string value = PrimeSDK.Data.GetString("key", defaultValue: "default"); PrimeSDK.Data.SetString("key", "value"); ` Получить и сохранить сериализуемый объект: `csharp using UnityEngine; Vector3 value = PrimeSDK.Data.GetObject("key", defaultValue: Vector3.zero); PrimeSDK.Data.SetObject("key", Vector3.one); ` Сохранить несколько значений без автосохранения на каждом Set-вызове: `csharp PrimeSDK.Data.SetInt("coins", 512, important: false); PrimeSDK.Data.SetFloat("volume", 0.75f, important: false); PrimeSDK.Data.SetString("player_name", "Prime", important: false); PrimeSDK.Data.Save(); ` Проверить наличие данных по ключу, удалить ключ или удалить все сохранения: `csharp bool valueExists = PrimeSDK.Data.HasKey("key"); PrimeSDK.Data.DeleteKey("key"); PrimeSDK.Data.DeleteAll(); ` ## Настройки звука PrimeSDK.Audio управляет громкостью и аудио-паузой через единый SDK API. При интеграции PrimeSDK замените прямые обращения к `AudioListener.volume` на `PrimeSDK.Audio.Volume`, а обращения к `AudioListener.pause` на `PrimeSDK.Audio.Pause`. SDK использует эти значения при обработке паузы, фокуса приложения и возобновления игры. Такой подход помогает избежать конфликтов: PrimeSDK может временно поставить звук на паузу или обнулить громкость во время системной паузы, а затем восстановить значения, которые были установлены через `PrimeSDK.Audio`. Получить и установить текущую громкость аудио: `csharp using UnityEngine; float currentVolume = PrimeSDK.Audio.Volume; PrimeSDK.Audio.Volume = Mathf.Clamp01(newVolume); ` Получить и установить состояние паузы аудио: `csharp bool isAudioPaused = PrimeSDK.Audio.Pause; PrimeSDK.Audio.Pause = true; ` Перед обращением к `PrimeSDK.Audio` дождитесь готовности SDK через `PrimeSDK.WaitForProviders(...)`, как и для остальных провайдеров. ## Устройство PrimeSDK.Device предоставляет информацию об устройстве, управляет курсором и открывает внешние ссылки. Перед обращением к `PrimeSDK.Device` дождитесь готовности SDK через `PrimeSDK.WaitForProviders(...)`. В актуальном API свойства устройства, курсора и браузера доступны через единый фасад `PrimeSDK.Device`. Проверить, является ли устройство мобильным, и получить тип операционной системы: `csharp using PrimeGames.SDK.Common; bool isMobile = PrimeSDK.Device.IsMobile; SystemType systemType = PrimeSDK.Device.SystemType; ` `SystemType` может принимать значения `Unknown`, `Android`, `iOS`, `Windows`, `Linux`, `Mac`. Показать или спрятать курсор: `csharp // Показать курсор PrimeSDK.Device.CursorVisible = true; // Спрятать курсор PrimeSDK.Device.CursorVisible = false; ` Заблокировать или разблокировать курсор: `csharp using UnityEngine; // Заблокировать курсор PrimeSDK.Device.CursorLock = CursorLockMode.Locked; // Разблокировать курсор PrimeSDK.Device.CursorLock = CursorLockMode.None; ` PrimeSDK кэширует значения `CursorVisible` и `CursorLock`, поэтому во время системной паузы SDK может временно показать и разблокировать курсор, а после возобновления восстановить значения, установленные через `PrimeSDK.Device`. Открыть страницу в браузере: `csharp PrimeSDK.Device.OpenUrl("https://example.com"); ` ## Локализация PrimeSDK.Language возвращает язык платформы, который нужно использовать для выбора локализации игры. Для прохождения модерации на большинстве веб-площадок локализацию игры нужно привязывать к языку, который возвращает `PrimeSDK.Language.Current`. Не используйте только локальные настройки Unity или собственный выбор языка как единственный источник истины при первом запуске на площадке. Перед чтением языка дождитесь готовности SDK через `PrimeSDK.WaitForProviders(...)`, потому что язык может приходить от платформенного провайдера. Получить текущий язык платформы: `csharp using PrimeGames.SDK.Common; LanguageType languageType = PrimeSDK.Language.Current; ` Пример выбора локали игры: `csharp using PrimeGames.SDK; using PrimeGames.SDK.Common; using UnityEngine; public class GameLocalization : MonoBehaviour { private void Start() { PrimeSDK.WaitForProviders(ApplyPlatformLanguage); } private void ApplyPlatformLanguage() { LanguageType language = PrimeSDK.Language.Current; switch (language) { case LanguageType.Russian: ApplyLocale("ru"); break; case LanguageType.Turkish: ApplyLocale("tr"); break; case LanguageType.German: ApplyLocale("de"); break; case LanguageType.Spanish: ApplyLocale("es"); break; default: ApplyLocale("en"); break; } } private void ApplyLocale(string localeCode) { Debug.Log($"Apply locale: {localeCode}"); // Подключите здесь вашу систему локализации. } } ` ## Внутриигровые покупки PrimeSDK.Payments предоставляет API для покупки товаров, получения информации о товарах и восстановления невыданных покупок. Перед обращением к `PrimeSDK.Payments` дождитесь готовности SDK через `PrimeSDK.WaitForProviders(...)`. В текущем API нет свойства `PrimeSDK.Payments.IsAvailable`, поэтому доступность покупок определяется выбранной платформой и провайдером. Если покупки не поддерживаются, fallback-провайдер вызовет `onError` при покупке и вернет пустые или стандартные данные. Начать покупку товара: `csharp using PrimeGames.SDK; using UnityEngine; PrimeSDK.WaitForProviders(() => { PrimeSDK.Payments.Purchase( productTag: "exampleProduct", onSuccess: () => { Debug.Log("Товар успешно куплен"); GiveProduct("exampleProduct"); }, onError: () => Debug.Log("Товар не был куплен") ); }); void GiveProduct(string productTag) { // Выдайте товар игроку. } ` Получить информацию о товаре: `csharp using PrimeGames.SDK.Common; using UnityEngine; ProductData productData = PrimeSDK.Payments.GetProductData("exampleProduct"); Debug.Log($"Тег продукта: {productData.Tag}"); Debug.Log($"Цена продукта (int): {productData.PriceInteger}"); Debug.Log($"Цена продукта (float): {productData.PriceFloat}"); Debug.Log($"Валюта продукта: {productData.Currency}"); string fullPriceInteger = productData.GetFullPriceInteger(); string fullPriceFloat = productData.GetFullPriceFloat(); ` Проверить, был ли товар уже куплен хотя бы один раз: `csharp bool isAlreadyPurchased = PrimeSDK.Payments.IsAlreadyPurchased("exampleProduct"); ` Восстановление покупок нужно для случаев, когда оплата прошла успешно, но игрок не получил товар из-за потери соединения, закрытия страницы или вылета игры. Метод `RestorePurchases` возвращает `IRestoreData` со списком всех покупок и списком товаров, которые еще нужно выдать. `csharp using PrimeGames.SDK.Common; using UnityEngine; PrimeSDK.Payments.RestorePurchases((IRestoreData restoreData) => { if (restoreData == null) { Debug.Log("Восстановление покупок недоступно"); return; } string[] allPurchases = restoreData.AllPurchases; Debug.Log($"Игрок совершил {allPurchases.Length} успешных покупок"); string[] pendingProducts = restoreData.PendingProducts; Debug.Log($"Невыданные товары: [{string.Join(", ", pendingProducts)}]"); foreach (string productTag in pendingProducts) { restoreData.RestoreProduct(productTag, onProductRestore: () => { GiveProduct(productTag); Debug.Log($"Товар {productTag} восстановлен"); }); } }); ` `RestoreProduct` можно вызывать повторно: если товар уже зарегистрирован как выданный, он не будет выдан повторно. Callback `onProductRestore` будет вызван столько раз, сколько оплаченных экземпляров товара еще не было выдано игроку. Восстановить конкретный товар из полученного `IRestoreData`: `csharp restoreData.RestoreProduct( productTag: "exampleProduct", onProductRestore: () => { GiveProduct("exampleProduct"); Debug.Log("Товар exampleProduct восстановлен"); } ); ` ## Xsolla Xsolla подключается к PrimeSDK как провайдер внутриигровых покупок для Web/CrazyGames. Пакет `XSolla Web API for PrimeSDK` не добавляет отдельный публичный API для игры. После установки и выбора провайдера `CrazyGamesXSollaPayments` проект продолжает обращаться к покупкам через общий интерфейс `PrimeSDK.Payments`. Текущая интеграция предназначена для Web-версии Xsolla, а не для мобильной Xsolla-интеграции. Она использует официальный Xsolla Unity Commerce SDK и платформенный логин CrazyGames. Принцип работы: - PrimeSDK загружает платформенный слой CrazyGames и получает Xsolla user token через `CrazyGames.SDK.user.getXsollaUserToken()`. - Провайдер передает токен в Xsolla Unity Commerce SDK через `XsollaToken.Create(...)`. - Каталог товаров загружается из Xsolla через `XsollaCatalog.GetItems(...)` и преобразуется в `ProductData`. - Покупка запускается через `PrimeSDK.Payments.Purchase(...)`, а внутри провайдера выполняется `XsollaCatalog.Purchase(...)`. - Восстановление покупок идет через `PrimeSDK.Payments.RestorePurchases(...)`, внутри провайдера читается инвентарь Xsolla через `XsollaInventory.GetInventoryItems(...)`. Для установки через PrimeSDK Toolkit используйте пакет `XSolla Web API for PrimeSDK`. Автоматическая установка должна сначала добавить официальный Xsolla Unity Commerce SDK, а затем API-пакет PrimeSDK. `text https://raw.githubusercontent.com/xsolla/store-unity-sdk/master/xsolla-unity-sdk-latest.unitypackage https://github.com/Prime-SDK/SDK-XSolla-API.git ` После установки в окне PrimeSDK выберите `CrazyGamesXSollaPayments` в `PrimeWebConfiguration` и используйте `PrimeWebConfiguration` как build configuration для WebGL-сборки. Пример покупки через Xsolla-провайдер не отличается от общего API покупок: `csharp PrimeSDK.WaitForProviders(() => { PrimeSDK.Payments.Purchase( productTag: "coins_pack_1", onSuccess: () => { GiveProduct("coins_pack_1"); Debug.Log("Xsolla purchase completed"); }, onError: () => Debug.Log("Xsolla purchase failed") ); }); ` При покупке провайдер проверяет авторизацию CrazyGames. Если игрок не авторизован, вызывается платформенный login flow. Если игрок откажется от авторизации или Xsolla вернет ошибку, будет вызван `onError`. Информация о товаре берется из каталога Xsolla. `productTag` в PrimeSDK должен совпадать с `sku` товара в Xsolla. `csharp using PrimeGames.SDK.Common; ProductData product = PrimeSDK.Payments.GetProductData("coins_pack_1"); Debug.Log($"{product.Tag}: {product.GetFullPriceFloat()}"); ` Восстановление покупок также выполняется через общий API. Провайдер получает инвентарь Xsolla, сравнивает оплаченные товары с уже выданными и возвращает `PendingProducts`. `csharp PrimeSDK.Payments.RestorePurchases((IRestoreData restoreData) => { if (restoreData == null) { return; } foreach (string productTag in restoreData.PendingProducts) { restoreData.RestoreProduct(productTag, () => GiveProduct(productTag)); } }); ` ## Playgama Playgama API for PrimeSDK подключает Playgama Bridge к единым интерфейсам PrimeSDK. Модуль Playgama не добавляет отдельный игровой API. Он добавляет конфигурацию `PlaygamaConfiguration`, которая подменяет провайдеры PrimeSDK на реализации поверх Playgama Bridge. После выбора этой конфигурации игровой код продолжает работать через `PrimeSDK.Ads`, `PrimeSDK.Data`, `PrimeSDK.Analytics`, `PrimeSDK.Payments`, `PrimeSDK.Player`, `PrimeSDK.Platform`, `PrimeSDK.Language`, `PrimeSDK.Device`, `PrimeSDK.Audio` и `PrimeSDK.Achievements`. Для установки модуль требует официальный Playgama Bridge Unity SDK. При установке через PrimeSDK Toolkit используйте автоматическую установку: сначала будет добавлен `com.playgama.bridge`, затем пакет PrimeSDK API. `text https://github.com/playgama/bridge-unity.git https://github.com/Prime-SDK/SDK-Playgama-API.git ` Перед установкой удалите старые вручную импортированные копии Playgama Bridge, если они есть в `Assets/WebGLTemplates`, `Assets/PlayGamaBridge` или `Assets/Plugins/PlaygamaBridge.jslib`. Дубли старого SDK могут конфликтовать с пакетной установкой. После установки выберите `PlaygamaConfiguration` в PrimeSDK Toolkit как build configuration для WebGL-сборки. Что покрывает `PlaygamaConfiguration`: - `PrimeSDK.Ads` работает через `Bridge.advertisement` и поддерживает banner, interstitial и rewarded, если они поддерживаются текущей площадкой. - `PrimeSDK.Data` сохраняет общий JSON прогресса через `Bridge.storage` по ключу `json-data`. - `PrimeSDK.Analytics.GameIsReady`, `GameplayStart` и `GameplayStop` отправляют платформенные сообщения Playgama Bridge. - `PrimeSDK.Payments` получает каталог, покупки и запускает оплату через `Bridge.payments`. - `PrimeSDK.Player` читает данные игрока через `Bridge.player` и запускает авторизацию через `Bridge.player.Authorize(...)`. - `PrimeSDK.Platform` определяет площадку по `Bridge.platform.id` и вызывает share/rate через `Bridge.social`. - `PrimeSDK.Language`, `PrimeSDK.Device`, `PrimeSDK.Audio`, `PrimeSDK.Achievements` используют соответствующие модули Playgama Bridge. Пример рекламы через Playgama-модуль не отличается от общего API PrimeSDK: `csharp PrimeSDK.WaitForProviders(() => { if (PrimeSDK.Ads.IsRewardedAvailable && PrimeSDK.Ads.IsRewardedReady) { PrimeSDK.Ads.InvokeRewarded( onOpen: () => Debug.Log("Rewarded opened"), onClose: isSuccess => Debug.Log($"Rewarded closed: {isSuccess}"), rewardTag: "extra_lives" ); } }); ` Пример сохранения прогресса через Playgama storage: `csharp PrimeSDK.Data.SetInt("coins", 100); PrimeSDK.Data.Save(); int coins = PrimeSDK.Data.GetInt("coins", defaultValue: 0); ` Пример определения площадки внутри Playgama: `csharp using PrimeGames.SDK.Common; PlatformType platform = PrimeSDK.Platform.Current; if (platform == PlatformType.YandexGames) { PrimeSDK.Analytics.GameIsReady(); } ` Remote config в текущей реализации `PrimeSDK.Flags` доступен только для Playgama-платформы `yandex`; на остальных площадках флаги считаются недоступными и возвращают значения по умолчанию. Часть возможностей зависит от конкретной площадки внутри Playgama. Например, реклама, платежи, лидерборды, achievements, share и rate должны поддерживаться самой площадкой, иначе соответствующий вызов может ничего не сделать, вернуть пустые данные или завершиться через error callback. ## Web Template PrimeGames WebGL Template - это WebGL-шаблон Unity для сборок PrimeSDK. Модуль Web Template поставляется отдельным пакетом `com.primesdk.primegames.template`. Он не добавляет C# API и не меняет игровую логику; его задача - оформить WebGL-сборку и подготовить корректную HTML-обвязку для запуска Unity в браузере. При установке через PrimeSDK Package Manager шаблон скачивается из репозитория `Prime-SDK/PrimeGamesTemplate` и копируется в проект Unity: `text Assets/WebGLTemplates/PrimeGames ` После установки выберите шаблон в Unity: `Project Settings -> Player -> WebGL -> Resolution and Presentation -> WebGL Template -> PrimeGames`. Что входит в шаблон: - `index.html` - HTML-страница сборки с Unity canvas, loading bar и подключением `unityApp.js`. - `unityApp.js` - запуск Unity loader, настройка canvas, отключение нежелательного scroll/context menu и обработка параметров шаблона. - `TemplateData/style.css` - стили страницы, фона, логотипа загрузки и progress bar. - `gameBackground.png` - фон страницы за Unity canvas. - `gameIcon.png` - картинка загрузочного логотипа. - `manifest.webmanifest`, `favicon.ico`, `thumbnail.png` и вспомогательные изображения TemplateData. Загрузчик показывает `#unity-loading-bar`, запускает `createUnityInstance(...)`, обновляет ширину `#unity-progress-bar-full` по прогрессу Unity и скрывает loading bar после успешного запуска игры. В текущей версии шаблона процент загрузки текстом не выводится. Прогресс отображается только визуально через заполнение progress bar. Шаблон поддерживает параметры Unity WebGL Template: - `PORTRAIT_ONLY` и `LANDSCAPE_ONLY` - показывают overlay с просьбой повернуть устройство, если пользователь держит телефон в неправильной ориентации. - `MOBILE_PORTRAIT_ASPECT_RATIO`, `MOBILE_LANDSCAPE_ASPECT_RATIO`, `DESKTOP_ASPECT_RATIO` - ограничивают соотношение сторон canvas. - `MATCH_WEBGL_TO_CANVAS_SIZE` - передается в Unity config как `matchWebGLToCanvasSize`. - `AUTO_SYNC_PERSISTENT_DATA_PATH` - передается в Unity config как `autoSyncPersistentDataPath`. - `DEVICE_PIXEL_RATIO` - задает `config.devicePixelRatio` для управления плотностью рендера. Для замены визуальных материалов редактируйте копию шаблона в `Assets/WebGLTemplates/PrimeGames`, а не пакет в `Packages`. Папка `Packages` может быть immutable, а изменения в ней могут потеряться после переустановки пакета. Основные файлы для кастомизации: - `gameBackground.png` - фон страницы. - `gameIcon.png` - логотип загрузки. - `TemplateData/style.css` - размеры, позиционирование, цвет фона и progress bar. - `manifest.webmanifest` - данные web manifest. - `TemplateData/favicon.ico` - favicon страницы. Если после сборки рядом с PNG появляются файлы с суффиксом `~`, это временные или резервные файлы, которые могут появляться при обработке/оптимизации изображений. Их не нужно подключать в шаблон и не нужно класть в финальный архив сборки. Рекомендуемый порядок использования: - Установите `PrimeGames WebGL Template` через PrimeSDK Package Manager. - Убедитесь, что папка `Assets/WebGLTemplates/PrimeGames` появилась в проекте. - Выберите шаблон `PrimeGames` в WebGL Player Settings. - При необходимости замените `gameBackground.png`, `gameIcon.png`, favicon и manifest в копии шаблона внутри `Assets`. - Соберите WebGL-проект через Build Optimizer или стандартный Unity Build. ## Build Optimizer Build Optimizer - это раздел PrimeSDK Toolkit для WebGL-сборки, анализа зависимостей и оптимизации импортируемых ассетов. Build Optimizer находится в окне PrimeSDK Toolkit и заменяет старый отдельный раздел Build Automation. Он объединяет настройки WebGL-сборки, запуск сборки, анализ зависимостей сцен и мастер оптимизации ассетов. Инструмент работает с enabled-сценами из Unity Build Settings. Если в Build Settings нет включенных сцен, анализ завершится ошибкой `No enabled scenes in Build Settings`. Основные действия: - `Build & Analyze` - выполняет WebGL-сборку, применяет выбранный export format, считает размер результата и затем анализирует зависимости включенных сцен. - `Analyze Only` - не запускает сборку, а только анализирует зависимости включенных сцен через `AssetDatabase.GetDependencies(...)`. - `Open Reports` - открывает папку `BuildReports` в корне проекта. После анализа интерфейс показывает: - `Build Size` - размер результата последней сборки, если запускался `Build & Analyze`. - `Tracked Assets` - количество ассетов, найденных в зависимостях включенных сцен. - `Estimated Assets` - суммарный размер исходных файлов ассетов. - `Build Breakdown` - разбивку по категориям `Texture`, `Audio`, `Model`, `Material`, `Shader`, `Font`, `Other`. - `Largest Assets` - самые крупные ассеты из анализа. Build Optimizer сохраняет отчет анализа в `BuildReports`. Отчет полезен, чтобы быстро найти тяжелые ассеты, которые попали в сборку через сцены. Раздел `Optimize Assets` - это мастер оптимизации импортируемых ассетов. Перед применением оптимизаций сначала запустите `Analyze Only` или `Build & Analyze`, чтобы мастер собрал список кандидатов. Мастер состоит из шагов: - `Overview` - сводка по кандидатам: Textures, Audio, Models, Materials. - `Textures` - настройки и список текстурных кандидатов. - `Audio` - настройки и список аудио-кандидатов. - `Models` - настройки и список моделей. - `Materials` - настройки и список материалов. - `Apply` - финальный просмотр выбранных ассетов и применение оптимизации. Важно: оптимизация меняет import settings ассетов в `Assets/`. Ассеты из `Packages/` не модифицируются. Перед массовым применением убедитесь, что проект находится под git или другой системой контроля версий. Оптимизация текстур может менять: - Max Size. - Generate MipMaps. - Texture Compression. - Crunch Compression. - Compression Quality. - Resize Algorithm. - Texture Format. - Platform overrides. - Фильтры по расширениям и Texture Importer Type. - Опциональное изменение исходных PNG/JPG-файлов, если включено `Resize PNG/JPG source files`. По умолчанию текстурная оптимизация исключает папку `WebGLTemplates`, чтобы не пережимать изображения WebGL-шаблона: фон, логотип, progress bar и favicon. Оптимизация аудио может менять: - Force To Mono. - Load In Background. - Preload Audio Data. - Load Type. - Compression Format. - Quality. - Sample Rate. - Фильтры по расширениям MP3, OGG, WAV. Оптимизация моделей может включать mesh compression, отключать Read/Write и включать optimize mesh, включая внутренние параметры `optimizeMesh`, `optimizeMeshPolygons` и `optimizeMeshVertices`, если они доступны в текущей версии Unity. Оптимизация материалов может менять GPU Instancing и, если включен `Change Shaders`, заменять материалы со старого shader name на новый shader name. Если новый shader не найден, оптимизатор запишет ошибку в лог и не поменяет материал. Применение оптимизаций запускается только после подтверждения Unity dialog. Во время применения PrimeSDK показывает progress bar, выполняет изменения через `AssetDatabase.StartAssetEditing()`, затем делает `AssetDatabase.Refresh()`. Рекомендуемый рабочий процесс: - Проверьте, что нужные сцены включены в Build Settings. - Откройте `PrimeSDK -> Build Optimizer`. - Настройте WebGL build settings и output format справа. - Запустите `Analyze Only`, чтобы увидеть зависимости и кандидатов без сборки. - Настройте шаги `Textures`, `Audio`, `Models`, `Materials` и снимите выделение с ассетов, которые нельзя менять. - Перейдите на `Apply` и примените изменения. - Соберите проект через `Build & Analyze` и сравните итоговый размер. > **Важно** > > После оптимизации необходимо проверить игру в браузере: четкость UI, читаемость текстур, качество аудио, корректность отображения моделей и материалов. ## RuStore Модуль RuStore подключает Android-интеграции RuStore к общему API PrimeSDK. RuStore API for PrimeSDK предназначен для Android-сборок. Пакет добавляет провайдеры для платежей, информации о платформе, статуса авторизации игрока и системного окна оценки приложения. Модуль не добавляет отдельную точку входа для игрового кода. После установки пакета проект продолжает работать через общий API PrimeSDK: `PrimeSDK.Payments`, `PrimeSDK.Platform` и `PrimeSDK.Player`. Что реализовано в текущем RuStore-модуле: - `RuStorePayments` - покупки, загрузка каталога товаров, проверка купленных товаров и восстановление покупок через RuStore Pay. - `RuStorePlatformInfo` - возвращает `PlatformType.RuStore` и `DeploymentType.Mobile`. - `RuStorePlatformInteractions` - вызывает RuStore Review Flow через `PrimeSDK.Platform.RateGame()`. - `RuStorePlayerAccount` - проверяет статус авторизации пользователя RuStore Pay и отдает его через общий player API. Ограничения текущей реализации: - Работает только на Android: assembly `PrimeGames.SDK.RuStore` ограничен платформой Android. - `PrimeSDK.Platform.ShareGame(...)` для RuStore сейчас не реализован. - `PrimeSDK.Platform.AppId` возвращает стандартное значение, потому что app id не читается из RuStore-пакета. - Подписки RuStore Pay сейчас игнорируются; поддерживаются product purchases. - Данные профиля игрока вроде имени, username и unique id сейчас не заполняются, доступен только статус авторизации. Перед использованием установите пакет `RuStore API for PrimeSDK` через PrimeSDK Package Manager. Он подтягивает зависимости RuStore Core, RuStore Pay, RuStore Review и `RuStoreSDKSettings.unitypackage`. Список товаров задается в настройках провайдера `RuStorePayments` через поле `ProductsJson`. Это JSON-массив тегов товаров, которые должны совпадать с product id в кабинете RuStore. `json { "Values": ["coins_pack_1", "remove_ads", "starter_bundle"] } ` После старта провайдера PrimeSDK проверяет доступность платежей через `RuStorePayClient.Instance.GetPurchaseAvailability`, загружает товары через `GetProducts` и получает список покупок через `GetPurchases`. Поэтому перед обращением к платежам нужно дождаться `PrimeSDK.WaitForProviders(...)`. `csharp using PrimeGames.SDK; using PrimeGames.SDK.Common; using UnityEngine; PrimeSDK.WaitForProviders(() => { ProductData product = PrimeSDK.Payments.GetProductData("coins_pack_1"); Debug.Log($"{product.Tag}: {product.GetFullPriceFloat()}"); }); ` Покупка товара выполняется через общий API `PrimeSDK.Payments.Purchase(...)`. Внутри RuStore-провайдера вызывается `RuStorePayClient.Instance.Purchase(...)` с `PreferredPurchaseType.ONE_STEP`. `csharp PrimeSDK.Payments.Purchase( productTag: "coins_pack_1", onSuccess: () => { GiveProduct("coins_pack_1"); Debug.Log("RuStore purchase completed"); }, onError: () => Debug.Log("RuStore purchase failed") ); ` Восстановление покупок также идет через общий API. Провайдер повторно читает покупки RuStore, сравнивает их с уже выданными товарами PrimeSDK и возвращает `IRestoreData`. `csharp PrimeSDK.Payments.RestorePurchases((IRestoreData restoreData) => { if (restoreData == null) { return; } foreach (string productTag in restoreData.PendingProducts) { restoreData.RestoreProduct(productTag, () => GiveProduct(productTag)); } }); ` Окно оценки приложения вызывается через общий платформенный API: `csharp PrimeSDK.Platform.RateGame(); ` Для проверки платформы используйте общий API PrimeSDK: `csharp PlatformType platform = PrimeSDK.Platform.Current; // RuStore DeploymentType deployment = PrimeSDK.Platform.Deployment; // Mobile ` ## Yandex Mobile Ads Модуль Yandex Mobile Ads подключает мобильную рекламу Яндекса к общему API PrimeSDK.Ads. Yandex Mobile Ads API for PrimeSDK предназначен для мобильной рекламы в Android-сборках. Пакет добавляет провайдер `YandexMobileAds` для интерфейса `IAds`; отдельный игровой API не появляется. После установки игровой код продолжает работать через общий API `PrimeSDK.Ads`. В Toolkit нужно открыть нужную Android-конфигурацию, перейти в foldout `Ads`, включить `Use custom` и выбрать `YandexMobileAds` как провайдер рекламы. Что реализовано в текущем модуле: - Межстраничная реклама через `PrimeSDK.Ads.InvokeInterstitial(...)`. - Rewarded-реклама через `PrimeSDK.Ads.InvokeRewarded(...)`. - Загрузка рекламы выполняется при вызове показа: провайдер создает `InterstitialAdLoader` или `RewardedAdLoader`, загружает объявление и сразу показывает его после успешной загрузки. - При успешном показе `onOpen` вызывается после события `OnAdShown`. - Для interstitial `onClose(true)` вызывается после `OnAdDismissed`; при ошибке загрузки или показа вызывается `onClose(false)`. - Для rewarded `onClose(true)` вызывается только если Yandex SDK прислал событие `OnRewarded`; иначе закрытие считается неуспешным. Что сейчас не поддерживается: - Баннеры не реализованы в этом провайдере: `InvokeBanner`, `RefreshBanner` и `DisableBanner` только пишут warning. - `rewardTag` передается через общий API PrimeSDK, но внутри Yandex Mobile Ads не используется для выбора блока. Для выбора блока используются поля конфигурации `RewardedAdUnitIdAndroid` и `RewardedAdUnitIdIOS`. - В текущем asmdef пакет ограничен Android/Editor и `UNITY_ANDROID`; несмотря на наличие iOS-полей в конфигурации, текущая интеграция в PrimeSDK ориентирована на Android. Зависимости устанавливаются через OpenUPM: `com.google.external-dependency-manager` и `com.yandex.mobileads`. Если ставите модуль через PrimeSDK Package Manager, Toolkit должен добавить эти зависимости автоматически. Для ручной установки нужно добавить scoped registry OpenUPM с URL `https://package.openupm.com` и scopes `com.yandex`, `com.google`, затем установить `External Dependency Manager for Unity`, `Yandex Mobile Ads plugin for Unity` и сам API-пакет PrimeSDK. После установки Yandex Mobile Ads обязательно выполните `Force Resolve` через External Dependency Manager и убедитесь, что резолв зависимостей завершился без ошибок перед Android-сборкой. Настройки провайдера: - `Interstitial UID Android` - ad unit id для межстраничной рекламы на Android. - `Rewarded UID Android` - ad unit id для rewarded-рекламы на Android. - `Interstitial UID iOS` и `Rewarded UID iOS` есть в классе конфигурации, но текущий пакет PrimeSDK собирается как Android-интеграция. Для тестов можно использовать demo ad unit ids Яндекса, но их нельзя оставлять в production-сборке. Пример показа interstitial: `csharp using PrimeGames.SDK; using UnityEngine; PrimeSDK.WaitForProviders(() => { if (!PrimeSDK.Ads.IsInterstitialAvailable) { Debug.Log("Yandex interstitial is not available"); return; } PrimeSDK.Ads.InvokeInterstitial( onOpen: () => Debug.Log("Yandex interstitial opened"), onClose: isSuccess => Debug.Log($"Yandex interstitial closed. Success: {isSuccess}") ); }); ` Пример показа rewarded-рекламы: `csharp PrimeSDK.WaitForProviders(() => { if (!PrimeSDK.Ads.IsRewardedAvailable) { Debug.Log("Yandex rewarded is not available"); return; } PrimeSDK.Ads.InvokeRewarded( onOpen: () => Debug.Log("Yandex rewarded opened"), onClose: isSuccess => { if (isSuccess) { GiveReward(); } Debug.Log($"Yandex rewarded closed. Reward granted: {isSuccess}"); }, rewardTag: "extra_lives" ); }); ` Так как объявление грузится при вызове показа, не завязывайте логику Yandex Mobile Ads на `IsInterstitialReady` или `IsRewardedReady`. Для этого провайдера надежнее проверять `IsInterstitialAvailable` / `IsRewardedAvailable` и обрабатывать результат в `onClose`. ## Площадка PrimeSDK.Platform сообщает, на какой площадке и в каком окружении запущена игра, а также предоставляет действия платформы. Перед обращением к `PrimeSDK.Platform` дождитесь готовности SDK через `PrimeSDK.WaitForProviders(...)`. В WebGL-конфигурации `Current` определяется платформенным слоем PrimeWeb, `Deployment` обычно возвращает `Web`, а `AppId` приходит от площадки, если она предоставляет идентификатор приложения. Получить тип платформы, тип окружения и уникальный идентификатор игры на платформе: `csharp using PrimeGames.SDK.Common; PlatformType platform = PrimeSDK.Platform.Current; DeploymentType deployment = PrimeSDK.Platform.Deployment; string appId = PrimeSDK.Platform.AppId; ` `DeploymentType` может принимать значения `Unknown`, `Editor`, `Web`, `Mobile`, `Standalone`, `Console`. `PlatformType` содержит конкретные площадки и магазины, например `YandexGames`, `CrazyGames`, `GameDistribution`, `VK`, `OK`, `MSN`, `Xiaomi`, `RuStore`, `GooglePlay`, `Steam` и другие. Поделиться игрой: `csharp PrimeSDK.Platform.ShareGame("message text"); ` Оценить игру: `csharp PrimeSDK.Platform.RateGame(); ` Пример платформенной логики: `csharp using PrimeGames.SDK; using PrimeGames.SDK.Common; using UnityEngine; PrimeSDK.WaitForProviders(() => { PlatformType platform = PrimeSDK.Platform.Current; if (platform == PlatformType.VK || platform == PlatformType.OK) { PrimeSDK.Platform.ShareGame("Попробуй мою игру!"); } Debug.Log($"Platform: {platform}, deployment: {PrimeSDK.Platform.Deployment}, appId: {PrimeSDK.Platform.AppId}"); }); ` > **Важно** > > Если текущая платформа не поддерживает методы `ShareGame` или `RateGame`, fallback-провайдер просто залогирует предупреждение без выполнения какого-либо платформенного действия. ## Время PrimeSDK.Time управляет скоростью времени и предоставляет текущую дату и праздник. При интеграции PrimeSDK замените прямые обращения к `Time.timeScale` на `PrimeSDK.Time.Scale`. SDK использует масштаб времени для обработки паузы и возобновления игры, поэтому прямые изменения `Time.timeScale` могут конфликтовать с системной паузой, рекламой или потерей фокуса. `PrimeSDK.Time.Scale` кэширует значение, которое задает игра. Когда SDK переводит игру в паузу, фактический `Time.timeScale` может временно стать `0`, а после возобновления SDK восстановит сохраненное значение `PrimeSDK.Time.Scale`. Получить и изменить скорость времени: `csharp float timeScale = PrimeSDK.Time.Scale; PrimeSDK.Time.Scale = 1.0f; ` Получить текущее время в виде `DateTime`: `csharp using System; DateTime currentDate = PrimeSDK.Time.CurrentDate; ` Получить текущий праздник: `csharp using PrimeGames.SDK.Common; HolidayType holiday = PrimeSDK.Time.CurrentHoliday; ` В текущем API `HolidayType` может принимать значения `None`, `NewYear`, `Halloween`, `Easter`. Стандартный провайдер даты использует локальное `DateTime.Now`. Пример реакции на праздничный период: `csharp using PrimeGames.SDK.Common; if (PrimeSDK.Time.CurrentHoliday == HolidayType.Halloween) { EnableHalloweenTheme(); } void EnableHalloweenTheme() { // Включите праздничные ассеты или события. } ` ## English # PrimeSDK Documentation Documentation about the purpose of PrimeSDK, its features, and core principles - in a format that is convenient for both developers and AI agents. Version: 5.1.53 Install URL: https://github.com/Prime-SDK/PrimeSDK.git ## What Prime SDK Is For PrimeSDK exists to combine Unity project platform integrations into one managed layer. Cross-platform multipurpose plugin for Unity PrimeSDK helps simplify development and make project code cleaner and easier to read. Instead of directly integrating many different plugins, you can use the unified PrimeSDK API. The main task of PrimeSDK is to provide a universal abstract interface for key game services: ads, payments, analytics, data saving and other tools commonly used in development. You choose the required providers, connect them to PrimeSDK and work through a unified API. This reduces project complexity, simplifies code maintenance and helps adapt the game to different platforms faster. PrimeSDK is focused on WebGL and platform integrations. Support for specific features depends on the selected configuration, installed API packages and the capabilities of the platform itself. > **Important** > > Full Prime SDK functionality is supported only when the project's existing API is fully replaced with the Prime SDK API. Otherwise, some SDK features may be unavailable or work incorrectly. Currently supported integrations: - PrimeWeb / WebGL - Yandex Games - CrazyGames - GameDistribution - Playgama / Playgama Bridge - Y8 - MSN - Xiaomi - Lagged - Poki - RuStore - Yandex Mobile Ads - Xsolla Web for CrazyGames ## Installation and Setup PrimeSDK is installed in Unity through Package Manager by Git URL and then configured from the PrimeSDK window. Before installing PrimeSDK, make sure there are no compilation errors in Unity Console. Otherwise, the package may be displayed incorrectly until all existing project errors are fixed. Also make sure there are no other PrimeSDK versions installed in the project, because different SDK versions can conflict with each other. You can temporarily add PrimeSDK alongside previous versions if you need to migrate project code gradually. However, while several SDK versions are installed in the project at the same time, the project may work incorrectly. If critical errors such as `SDK is initialized multiple times` or `SDK instance already exists` appear after building a project with PrimeSDK for WebGL, check that the project does not contain conflicting WebGL native code. For example, `.jslib` or `.jspre` libraries from other plugins that directly interact with WebGL platform APIs. To add the package to the project, open Unity Package Manager, choose `Add package from git URL...` and enter ```https://github.com/Prime-SDK/PrimeSDK.git``` ## Initialization PrimeSDK can be used only after the SDK instance is created and all asynchronous providers from the selected configuration are ready. PrimeSDK interfaces should be accessed only after you make sure the SDK is initialized and ready. Before that, calls to SDK interfaces may throw exceptions, cause critical errors or crash the game. The current PrimeSDK API does not expose a public `IsInitialized` property. Instead of checking a readiness property directly, use `PrimeSDK.WaitForProviders(...)`. This method invokes a callback when all selected configuration components that require asynchronous loading are ready. Create the SDK instance before waiting for providers: `csharp using PrimeGames.SDK; PrimeSDK.CreateInstance(); ` Example 1. Using a coroutine: `csharp using System.Collections; using PrimeGames.SDK; using UnityEngine; public IEnumerator WaitForPrimeSDK() { bool isReady = false; PrimeSDK.WaitForProviders(() => { isReady = true; }); yield return new WaitUntil(() => isReady); // PrimeSDK is ready. } ` Example 2. Using a callback: `csharp PrimeSDK.WaitForProviders(() => { // PrimeSDK is ready. }); ` ## Ad Monetization PrimeSDK provides a unified API for banner, interstitial and rewarded ads through PrimeSDK.Ads. Wait for SDK readiness with `PrimeSDK.WaitForProviders(...)` before using ads. The current API does not expose a global `PrimeSDK.Ads.IsAvailable` property; availability is checked per ad type. `csharp bool isAnyAdsAvailable = PrimeSDK.Ads.IsBannerAvailable || PrimeSDK.Ads.IsInterstitialAvailable || PrimeSDK.Ads.IsRewardedAvailable; ` Banner ads > **Important** > > Banner ads are not supported by every platform. Check the official documentation of the platforms where you plan to publish your content for current banner ad support. `csharp bool isBannerReady = PrimeSDK.Ads.IsBannerReady; bool isBannerVisible = PrimeSDK.Ads.IsBannerVisible; bool isBannerAvailable = PrimeSDK.Ads.IsBannerAvailable; if (isBannerAvailable && isBannerReady) { PrimeSDK.Ads.InvokeBanner(); } ` Banner controls: `csharp PrimeSDK.Ads.InvokeBanner(); // show banner PrimeSDK.Ads.RefreshBanner(); // refresh banner content PrimeSDK.Ads.DisableBanner(); // hide banner ` Interstitial ads `csharp bool isInterstitialReady = PrimeSDK.Ads.IsInterstitialReady; bool isInterstitialVisible = PrimeSDK.Ads.IsInterstitialVisible; bool isInterstitialAvailable = PrimeSDK.Ads.IsInterstitialAvailable; ` `GetLastInterstitialSuccess()` returns the last successful interstitial close time. If no interstitial was successfully closed during the current session, it returns `null`. `csharp DateTime? lastInterstitialSuccess = PrimeSDK.Ads.GetLastInterstitialSuccess(); if (lastInterstitialSuccess.HasValue) { Debug.Log($"Last interstitial close time: {lastInterstitialSuccess.Value}"); TimeSpan timeSinceSuccess = DateTime.Now - lastInterstitialSuccess.Value; Debug.Log($"{timeSinceSuccess.TotalSeconds} seconds passed since the last interstitial close"); } else { Debug.Log("No interstitial was successfully closed during this game session"); } ` Showing an interstitial ad: `csharp PrimeSDK.Ads.InvokeInterstitial( onOpen: () => Debug.Log("Interstitial opened"), onClose: isSuccess => Debug.Log($"Interstitial closed. Success: {isSuccess}"), onAdBlockDetected: () => Debug.Log("AdBlock detected before showing an interstitial ad") ); ` Rewarded ads `csharp bool isRewardedReady = PrimeSDK.Ads.IsRewardedReady; bool isRewardedVisible = PrimeSDK.Ads.IsRewardedVisible; bool isRewardedAvailable = PrimeSDK.Ads.IsRewardedAvailable; ` `GetLastRewardedSuccess()` can be called without a tag to get the last successful close time of any rewarded ad, or with a tag to check a specific placement. If no successful close happened yet, it returns `null`. `csharp DateTime? lastRewardedSuccess = PrimeSDK.Ads.GetLastRewardedSuccess("extra_lives"); if (lastRewardedSuccess.HasValue) { Debug.Log($"Last extra_lives rewarded close time: {lastRewardedSuccess.Value}"); TimeSpan timeSinceSuccess = DateTime.Now - lastRewardedSuccess.Value; Debug.Log($"{timeSinceSuccess.TotalSeconds} seconds passed since extra_lives was closed"); } else { Debug.Log("extra_lives rewarded ad was not successfully closed during this game session"); } ` Showing a rewarded ad. The current API does not have a separate `onSuccess` callback; the reward result is passed to `onClose(bool isSuccess)`. `csharp PrimeSDK.Ads.InvokeRewarded( onOpen: () => Debug.Log("Rewarded ad opened"), onClose: isSuccess => { Debug.Log($"Rewarded ad closed. Reward granted: {isSuccess}"); if (isSuccess) { // Grant the reward to the player. } }, rewardTag: "extra_lives", onAdBlockDetected: () => Debug.Log("AdBlock detected before showing a rewarded ad") ); ` AdBlock Detection For interstitial and rewarded ads, you can pass `onAdBlockDetected`. The SDK checks for AdBlock only when an ad is requested. If an ad blocker is detected, the ad provider is not called: `onAdBlockDetected` is invoked first, then the ad flow finishes through `onClose(false)`. The check can be disabled in Ads Provider settings with `AdBlock Detection Enabled`. This setting belongs to the WebGL/PrimeWeb Ads Provider and does not start any continuous background detection. > **Important for CrazyGames** > > For CrazyGames, we recommend calling the styled `PrimeSDK.Pause.ShowContinuePrompt()` modal from `onAdBlockDetected`, because the platform uses a native overlay to notify players about active AdBlock. After that overlay is closed, the game window loses focus, the SDK pauses the game, and for the player this can look like the game is frozen, which often leads to moderation notes from the platform. ## Gameplay Events PrimeSDK supports basic gameplay events that platforms use to understand the current game state. Wait for SDK readiness with `PrimeSDK.WaitForProviders(...)` before sending gameplay events. The current API does not expose `PrimeSDK.Analytics.IsGameplayReporterAvailable`, so reporter availability is not checked through a bool property. This section covers gameplay state events only. Custom analytics events through `Report(...)` are intentionally not documented yet because the analytics backend is not ready. Continue prompt modal `PrimeSDK.Pause.ShowContinuePrompt(...)` shows a styled fullscreen prompt with the text “Click this area to continue.” The prompt is shown only when called manually through the API, does not pause the game by itself, and closes when the player clicks the prompt area. The method accepts an optional `onContinue` callback, which is invoked after the prompt is closed. Use it after external overlays or flows where the player needs an explicit action to return focus to the game. `csharp PrimeSDK.Pause.ShowContinuePrompt(() => { Debug.Log("Player continued the game"); }); ` Call Game Ready exactly when all progress bars, engine logos and startup screens are finished. The project must be ready for player interaction. If the screen shows story text, tutorial content or any other blocking flow, call Game Ready only after that flow ends and the player can interact with game elements. `csharp PrimeSDK.Analytics.GameIsReady(); ` Send Gameplay Start when gameplay enters the active state: the player is actually playing, not sitting in the main menu and the game is not paused. `csharp PrimeSDK.Analytics.GameplayStart(); ` Send Gameplay Restart when the player starts over, for example after losing or restarting a level. `csharp PrimeSDK.Analytics.GameplayRestart(); ` Send Gameplay Stop when gameplay enters a passive state: the player is not actively playing, is in a menu, the game is paused, or the active gameplay loop has ended. `csharp PrimeSDK.Analytics.GameplayStop(); ` Minimal lifecycle example: `csharp using PrimeGames.SDK; using UnityEngine; public sealed class GameplayEventsExample : MonoBehaviour { private void Start() { PrimeSDK.WaitForProviders(() => { PrimeSDK.Analytics.GameIsReady(); }); } public void StartGameplay() { PrimeSDK.Analytics.GameplayStart(); } public void RestartGameplay() { PrimeSDK.Analytics.GameplayRestart(); } public void StopGameplay() { PrimeSDK.Analytics.GameplayStop(); } } ` ## Achievements PrimeSDK provides API for Happy Time, achievements and leaderboards through PrimeSDK.Achievements. Wait for SDK readiness with `PrimeSDK.WaitForProviders(...)` before using achievements. Support for each method depends on the platform: if a platform does not support a feature, the provider may do nothing or log a warning. `HappyTime()` is relevant for CrazyGames and triggers the platform Happy Time effect. `csharp PrimeSDK.Achievements.HappyTime(); ` `Unlock(...)` is relevant for Lagged and unlocks an achievement by id. `csharp PrimeSDK.Achievements.Unlock("achievement_id"); ` Getting and saving a player score works only when the player is authorized and the platform supports leaderboards. > **Important** > > Prime SDK does not provide its own leaderboards. The SDK only calls platform APIs that support this functionality. If leaderboards are unavailable on the selected platform, the corresponding method will return an error. Check the official documentation of the platforms where you plan to publish your content for current leaderboard support. Get the player score from a leaderboard: `csharp PrimeSDK.Achievements.GetScore("leaderboard_id", score => { Debug.Log($"Player score: {score}"); }); ` Save the player score to a leaderboard: `csharp PrimeSDK.Achievements.SetScore("leaderboard_id", 100); ` The leaderboard player array may contain from 0 to 50 elements. In the current API, `Leaderboard.players` contains `PlayerScore` entries with `displayName`, `position`, `score`, `profilePictureUrl` fields. Get a leaderboard with player scores: `csharp using PrimeGames.SDK.Common; using UnityEngine; PrimeSDK.Achievements.GetLeaderboard("leaderboard_id", leaderboard => { PlayerScore[] players = leaderboard?.players ?? System.Array.Empty(); Debug.Log($"Received {players.Length} players from leaderboard_id"); foreach (PlayerScore player in players) { string displayName = player.displayName; int position = player.position; int score = player.score; string profilePictureUrl = player.profilePictureUrl; Debug.Log($"#{position} {displayName}: {score} ({profilePictureUrl})"); } }); ` ## Progress Saving PrimeSDK.Data stores player progress and provides methods for bool, int, float, string and serializable objects. Wait for SDK readiness with `PrimeSDK.WaitForProviders(...)` before using saved data. Every Get method has an optional `defaultValue` parameter used when the key is missing. For example, `PrimeSDK.Data.GetInt("key", 100)` returns `100` if the key is not found. Every Set method has an optional `important` parameter, which defaults to `true`. If you pass `important: false`, the value is changed in memory but automatic progress saving is not triggered. After a batch of such changes, call `PrimeSDK.Data.Save()` manually. Get and save a bool value: `csharp bool value = PrimeSDK.Data.GetBool("key", defaultValue: false); PrimeSDK.Data.SetBool("key", true); ` Get and save an int value: `csharp int value = PrimeSDK.Data.GetInt("key", defaultValue: 100); PrimeSDK.Data.SetInt("key", 512); ` Get and save a float value: `csharp float value = PrimeSDK.Data.GetFloat("key", defaultValue: 0.0f); PrimeSDK.Data.SetFloat("key", 3.14f); ` Get and save a string value: `csharp string value = PrimeSDK.Data.GetString("key", defaultValue: "default"); PrimeSDK.Data.SetString("key", "value"); ` Get and save a serializable object: `csharp using UnityEngine; Vector3 value = PrimeSDK.Data.GetObject("key", defaultValue: Vector3.zero); PrimeSDK.Data.SetObject("key", Vector3.one); ` Save several values without autosaving on every Set call: `csharp PrimeSDK.Data.SetInt("coins", 512, important: false); PrimeSDK.Data.SetFloat("volume", 0.75f, important: false); PrimeSDK.Data.SetString("player_name", "Prime", important: false); PrimeSDK.Data.Save(); ` Check if a key exists, delete one key or delete all saved data: `csharp bool valueExists = PrimeSDK.Data.HasKey("key"); PrimeSDK.Data.DeleteKey("key"); PrimeSDK.Data.DeleteAll(); ` ## Audio Settings PrimeSDK.Audio controls volume and audio pause through a single SDK API. When integrating PrimeSDK, replace direct `AudioListener.volume` usage with `PrimeSDK.Audio.Volume`, and direct `AudioListener.pause` usage with `PrimeSDK.Audio.Pause`. The SDK uses these values while handling pause, application focus and game resume behavior. This avoids conflicts: PrimeSDK can temporarily pause audio or set volume to zero during a system pause, then restore the values that were assigned through `PrimeSDK.Audio`. Get and set the current audio volume: `csharp using UnityEngine; float currentVolume = PrimeSDK.Audio.Volume; PrimeSDK.Audio.Volume = Mathf.Clamp01(newVolume); ` Get and set the current audio pause state: `csharp bool isAudioPaused = PrimeSDK.Audio.Pause; PrimeSDK.Audio.Pause = true; ` Before accessing `PrimeSDK.Audio`, wait for SDK readiness with `PrimeSDK.WaitForProviders(...)`, as with other providers. ## Device PrimeSDK.Device provides device information, cursor control and external link opening. Before accessing `PrimeSDK.Device`, wait for SDK readiness with `PrimeSDK.WaitForProviders(...)`. In the current API, device info, cursor and browser methods are exposed through the single `PrimeSDK.Device` facade. Check whether the device is mobile and get the operating system type: `csharp using PrimeGames.SDK.Common; bool isMobile = PrimeSDK.Device.IsMobile; SystemType systemType = PrimeSDK.Device.SystemType; ` `SystemType` can be `Unknown`, `Android`, `iOS`, `Windows`, `Linux`, `Mac`. Show or hide the cursor: `csharp // Show cursor PrimeSDK.Device.CursorVisible = true; // Hide cursor PrimeSDK.Device.CursorVisible = false; ` Lock or unlock the cursor: `csharp using UnityEngine; // Lock cursor PrimeSDK.Device.CursorLock = CursorLockMode.Locked; // Unlock cursor PrimeSDK.Device.CursorLock = CursorLockMode.None; ` PrimeSDK caches `CursorVisible` and `CursorLock` values, so during a system pause the SDK can temporarily show and unlock the cursor, then restore the values assigned through `PrimeSDK.Device` after resume. Open a page in the browser: `csharp PrimeSDK.Device.OpenUrl("https://example.com"); ` ## Localization PrimeSDK.Language returns the platform language that should be used to select the game localization. To pass moderation on most web platforms, bind the game localization to the language returned by `PrimeSDK.Language.Current`. Do not rely only on Unity local settings or a custom language selector as the only source of truth on the first platform launch. Before reading the language, wait for SDK readiness with `PrimeSDK.WaitForProviders(...)`, because the language can come from a platform provider. Get the current platform language: `csharp using PrimeGames.SDK.Common; LanguageType languageType = PrimeSDK.Language.Current; ` Example of selecting a game locale: `csharp using PrimeGames.SDK; using PrimeGames.SDK.Common; using UnityEngine; public class GameLocalization : MonoBehaviour { private void Start() { PrimeSDK.WaitForProviders(ApplyPlatformLanguage); } private void ApplyPlatformLanguage() { LanguageType language = PrimeSDK.Language.Current; switch (language) { case LanguageType.Russian: ApplyLocale("ru"); break; case LanguageType.Turkish: ApplyLocale("tr"); break; case LanguageType.German: ApplyLocale("de"); break; case LanguageType.Spanish: ApplyLocale("es"); break; default: ApplyLocale("en"); break; } } private void ApplyLocale(string localeCode) { Debug.Log($"Apply locale: {localeCode}"); // Connect your localization system here. } } ` ## In-App Purchases PrimeSDK.Payments provides API for purchasing products, reading product data and restoring pending purchases. Before accessing `PrimeSDK.Payments`, wait for SDK readiness with `PrimeSDK.WaitForProviders(...)`. The current API does not expose `PrimeSDK.Payments.IsAvailable`; purchase availability depends on the selected platform and provider. If payments are not supported, the fallback provider calls `onError` for purchases and returns empty or default data. Start a product purchase: `csharp using PrimeGames.SDK; using UnityEngine; PrimeSDK.WaitForProviders(() => { PrimeSDK.Payments.Purchase( productTag: "exampleProduct", onSuccess: () => { Debug.Log("Product purchased successfully"); GiveProduct("exampleProduct"); }, onError: () => Debug.Log("Product was not purchased") ); }); void GiveProduct(string productTag) { // Grant the product to the player. } ` Get product data: `csharp using PrimeGames.SDK.Common; using UnityEngine; ProductData productData = PrimeSDK.Payments.GetProductData("exampleProduct"); Debug.Log($"Product tag: {productData.Tag}"); Debug.Log($"Product price (int): {productData.PriceInteger}"); Debug.Log($"Product price (float): {productData.PriceFloat}"); Debug.Log($"Product currency: {productData.Currency}"); string fullPriceInteger = productData.GetFullPriceInteger(); string fullPriceFloat = productData.GetFullPriceFloat(); ` Check whether the product has been purchased at least once: `csharp bool isAlreadyPurchased = PrimeSDK.Payments.IsAlreadyPurchased("exampleProduct"); ` Purchase restoration covers cases where payment succeeded but the player did not receive the product because of connection loss, page close or a crash. `RestorePurchases` returns `IRestoreData` with all purchases and products that still need to be granted. `csharp using PrimeGames.SDK.Common; using UnityEngine; PrimeSDK.Payments.RestorePurchases((IRestoreData restoreData) => { if (restoreData == null) { Debug.Log("Purchase restore is not available"); return; } string[] allPurchases = restoreData.AllPurchases; Debug.Log($"Player completed {allPurchases.Length} successful purchases"); string[] pendingProducts = restoreData.PendingProducts; Debug.Log($"Pending products: [{string.Join(", ", pendingProducts)}]"); foreach (string productTag in pendingProducts) { restoreData.RestoreProduct(productTag, onProductRestore: () => { GiveProduct(productTag); Debug.Log($"Product {productTag} restored"); }); } }); ` `RestoreProduct` can be called repeatedly: if the product is already registered as supplied, it will not be granted again. The `onProductRestore` callback is called once for each paid product instance that has not yet been supplied to the player. Restore a specific product from an existing `IRestoreData` object: `csharp restoreData.RestoreProduct( productTag: "exampleProduct", onProductRestore: () => { GiveProduct("exampleProduct"); Debug.Log("Product exampleProduct restored"); } ); ` ## Xsolla Xsolla is connected to PrimeSDK as an in-app purchase provider for Web/CrazyGames. The `XSolla Web API for PrimeSDK` package does not add a separate public game API. After installation and selecting the `CrazyGamesXSollaPayments` provider, the game keeps using the common `PrimeSDK.Payments` interface. The current integration is for Web Xsolla, not for mobile Xsolla integration. It uses the official Xsolla Unity Commerce SDK and CrazyGames platform login. How it works: - PrimeSDK loads the CrazyGames platform layer and receives an Xsolla user token through `CrazyGames.SDK.user.getXsollaUserToken()`. - The provider passes the token to Xsolla Unity Commerce SDK through `XsollaToken.Create(...)`. - The product catalog is loaded from Xsolla through `XsollaCatalog.GetItems(...)` and converted into `ProductData`. - A purchase starts through `PrimeSDK.Payments.Purchase(...)`; internally the provider calls `XsollaCatalog.Purchase(...)`. - Purchase restoration goes through `PrimeSDK.Payments.RestorePurchases(...)`; internally the provider reads the Xsolla inventory with `XsollaInventory.GetInventoryItems(...)`. When installing from PrimeSDK Toolkit, use the `XSolla Web API for PrimeSDK` package. Automatic installation should add the official Xsolla Unity Commerce SDK first, then the PrimeSDK API package. `text https://raw.githubusercontent.com/xsolla/store-unity-sdk/master/xsolla-unity-sdk-latest.unitypackage https://github.com/Prime-SDK/SDK-XSolla-API.git ` After installation, open the PrimeSDK window, select `CrazyGamesXSollaPayments` in `PrimeWebConfiguration`, and use `PrimeWebConfiguration` as the build configuration for the WebGL build. A purchase through the Xsolla provider uses the same common payments API: `csharp PrimeSDK.WaitForProviders(() => { PrimeSDK.Payments.Purchase( productTag: "coins_pack_1", onSuccess: () => { GiveProduct("coins_pack_1"); Debug.Log("Xsolla purchase completed"); }, onError: () => Debug.Log("Xsolla purchase failed") ); }); ` During purchase, the provider checks CrazyGames authorization. If the player is not logged in, the platform login flow is invoked. If the player rejects login or Xsolla returns an error, `onError` is called. Product data comes from the Xsolla catalog. The PrimeSDK `productTag` must match the Xsolla product `sku`. `csharp using PrimeGames.SDK.Common; ProductData product = PrimeSDK.Payments.GetProductData("coins_pack_1"); Debug.Log($"{product.Tag}: {product.GetFullPriceFloat()}"); ` Purchase restoration also uses the common API. The provider receives the Xsolla inventory, compares paid products with already supplied products and returns `PendingProducts`. `csharp PrimeSDK.Payments.RestorePurchases((IRestoreData restoreData) => { if (restoreData == null) { return; } foreach (string productTag in restoreData.PendingProducts) { restoreData.RestoreProduct(productTag, () => GiveProduct(productTag)); } }); ` ## Playgama Playgama API for PrimeSDK connects Playgama Bridge to the unified PrimeSDK interfaces. The Playgama module does not add a separate game API. It adds `PlaygamaConfiguration`, which replaces PrimeSDK providers with implementations built on top of Playgama Bridge. After selecting this configuration, game code keeps using `PrimeSDK.Ads`, `PrimeSDK.Data`, `PrimeSDK.Analytics`, `PrimeSDK.Payments`, `PrimeSDK.Player`, `PrimeSDK.Platform`, `PrimeSDK.Language`, `PrimeSDK.Device`, `PrimeSDK.Audio` and `PrimeSDK.Achievements`. The module requires the official Playgama Bridge Unity SDK. When installing through PrimeSDK Toolkit, use automatic installation: it adds `com.playgama.bridge` first, then the PrimeSDK API package. `text https://github.com/playgama/bridge-unity.git https://github.com/Prime-SDK/SDK-Playgama-API.git ` Before installation, remove old manually imported Playgama Bridge copies if they exist in `Assets/WebGLTemplates`, `Assets/PlayGamaBridge` or `Assets/Plugins/PlaygamaBridge.jslib`. Old SDK duplicates can conflict with package installation. After installation, select `PlaygamaConfiguration` in PrimeSDK Toolkit as the build configuration for the WebGL build. What `PlaygamaConfiguration` covers: - `PrimeSDK.Ads` works through `Bridge.advertisement` and supports banner, interstitial and rewarded ads if the current platform supports them. - `PrimeSDK.Data` stores the shared progress JSON through `Bridge.storage` under the `json-data` key. - `PrimeSDK.Analytics.GameIsReady`, `GameplayStart` and `GameplayStop` send Playgama Bridge platform messages. - `PrimeSDK.Payments` loads the catalog, purchases and starts payments through `Bridge.payments`. - `PrimeSDK.Player` reads player data through `Bridge.player` and starts authorization through `Bridge.player.Authorize(...)`. - `PrimeSDK.Platform` detects the platform from `Bridge.platform.id` and calls share/rate through `Bridge.social`. - `PrimeSDK.Language`, `PrimeSDK.Device`, `PrimeSDK.Audio`, `PrimeSDK.Achievements` use the corresponding Playgama Bridge modules. Ads through the Playgama module use the same common PrimeSDK API: `csharp PrimeSDK.WaitForProviders(() => { if (PrimeSDK.Ads.IsRewardedAvailable && PrimeSDK.Ads.IsRewardedReady) { PrimeSDK.Ads.InvokeRewarded( onOpen: () => Debug.Log("Rewarded opened"), onClose: isSuccess => Debug.Log($"Rewarded closed: {isSuccess}"), rewardTag: "extra_lives" ); } }); ` Saving progress through Playgama storage: `csharp PrimeSDK.Data.SetInt("coins", 100); PrimeSDK.Data.Save(); int coins = PrimeSDK.Data.GetInt("coins", defaultValue: 0); ` Detecting the platform inside Playgama: `csharp using PrimeGames.SDK.Common; PlatformType platform = PrimeSDK.Platform.Current; if (platform == PlatformType.YandexGames) { PrimeSDK.Analytics.GameIsReady(); } ` Remote config in the current `PrimeSDK.Flags` implementation is available only for the Playgama `yandex` platform; on other platforms flags are considered unavailable and return default values. Some features depend on the specific platform inside Playgama. Ads, payments, leaderboards, achievements, share and rate must be supported by the platform itself; otherwise the corresponding call can do nothing, return empty data or finish through an error callback. ## Web Template PrimeGames WebGL Template is a Unity WebGL template for PrimeSDK builds. The Web Template module is distributed as the `com.primesdk.primegames.template` package. It does not add C# API and does not change gameplay logic; its purpose is to style the WebGL build and provide the HTML wrapper required to launch Unity in the browser. When installed through PrimeSDK Package Manager, the template is downloaded from the `Prime-SDK/PrimeGamesTemplate` repository and copied into the Unity project: `text Assets/WebGLTemplates/PrimeGames ` After installation, select the template in Unity: `Project Settings -> Player -> WebGL -> Resolution and Presentation -> WebGL Template -> PrimeGames`. Included files: - `index.html` - build HTML page with Unity canvas, loading bar and `unityApp.js` script. - `unityApp.js` - Unity loader startup, canvas setup, unwanted scroll/context menu prevention and template parameter handling. - `TemplateData/style.css` - page, background, loading logo and progress bar styles. - `gameBackground.png` - page background behind Unity canvas. - `gameIcon.png` - loading logo image. - `manifest.webmanifest`, `favicon.ico`, `thumbnail.png` and helper TemplateData images. The loader shows `#unity-loading-bar`, starts `createUnityInstance(...)`, updates `#unity-progress-bar-full` width from Unity loading progress and hides the loading bar after the game starts successfully. The current template does not render loading percentage as text. Progress is shown visually through the progress bar fill only. The template supports Unity WebGL Template parameters: - `PORTRAIT_ONLY` and `LANDSCAPE_ONLY` - show a rotation overlay when the device is held in the wrong orientation. - `MOBILE_PORTRAIT_ASPECT_RATIO`, `MOBILE_LANDSCAPE_ASPECT_RATIO`, `DESKTOP_ASPECT_RATIO` - constrain canvas aspect ratio. - `MATCH_WEBGL_TO_CANVAS_SIZE` - passed to Unity config as `matchWebGLToCanvasSize`. - `AUTO_SYNC_PERSISTENT_DATA_PATH` - passed to Unity config as `autoSyncPersistentDataPath`. - `DEVICE_PIXEL_RATIO` - sets `config.devicePixelRatio` to control render density. To replace visual assets, edit the template copy in `Assets/WebGLTemplates/PrimeGames`, not the package under `Packages`. The `Packages` folder can be immutable, and changes there may be lost after reinstalling the package. Main customization files: - `gameBackground.png` - page background. - `gameIcon.png` - loading logo. - `TemplateData/style.css` - sizes, positioning, background color and progress bar. - `manifest.webmanifest` - web manifest data. - `TemplateData/favicon.ico` - page favicon. If files with a `~` suffix appear next to PNG images after a build, they are temporary or backup files that may be created during image processing/optimization. They should not be referenced by the template and should not be included in the final build archive. Recommended usage flow: - Install `PrimeGames WebGL Template` through PrimeSDK Package Manager. - Make sure `Assets/WebGLTemplates/PrimeGames` exists in the project. - Select the `PrimeGames` template in WebGL Player Settings. - If needed, replace `gameBackground.png`, `gameIcon.png`, favicon and manifest in the template copy under `Assets`. - Build the WebGL project through Build Optimizer or the standard Unity Build flow. ## Build Optimizer Build Optimizer is a PrimeSDK Toolkit section for WebGL builds, dependency analysis and imported asset optimization. Build Optimizer lives inside PrimeSDK Toolkit and replaces the old separate Build Automation section. It combines WebGL build settings, build execution, enabled scene dependency analysis and the asset optimization wizard. The tool works with enabled scenes from Unity Build Settings. If there are no enabled scenes in Build Settings, analysis fails with `No enabled scenes in Build Settings`. Main actions: - `Build & Analyze` - runs a WebGL build, applies the selected export format, calculates output size and then analyzes enabled scene dependencies. - `Analyze Only` - does not run a build and only analyzes enabled scene dependencies with `AssetDatabase.GetDependencies(...)`. - `Open Reports` - opens the `BuildReports` folder in the project root. After analysis, the interface shows: - `Build Size` - output size of the latest build when `Build & Analyze` was used. - `Tracked Assets` - number of assets found in enabled scene dependencies. - `Estimated Assets` - total source file size of analyzed assets. - `Build Breakdown` - category breakdown: `Texture`, `Audio`, `Model`, `Material`, `Shader`, `Font`, `Other`. - `Largest Assets` - the largest assets from the analysis. Build Optimizer saves an analysis report into `BuildReports`. The report helps locate heavy assets that enter the build through scenes. `Optimize Assets` is an imported asset optimization wizard. Before applying optimizations, run `Analyze Only` or `Build & Analyze` so the wizard can populate candidates. Wizard steps: - `Overview` - candidate summary for Textures, Audio, Models and Materials. - `Textures` - texture settings and texture candidate list. - `Audio` - audio settings and audio candidate list. - `Models` - model settings and model candidate list. - `Materials` - material settings and material candidate list. - `Apply` - final selected asset preview and optimization application. Important: optimization changes import settings for assets under `Assets/`. Assets under `Packages/` are not modified. Before applying changes in bulk, make sure the project is under git or another version control system. Texture optimization can change: - Max Size. - Generate MipMaps. - Texture Compression. - Crunch Compression. - Compression Quality. - Resize Algorithm. - Texture Format. - Platform overrides. - Filters by extension and Texture Importer Type. - Optional PNG/JPG source file resizing when `Resize PNG/JPG source files` is enabled. By default, texture optimization excludes the `WebGLTemplates` folder to avoid recompressing WebGL template images: background, logo, progress bar and favicon. Audio optimization can change: - Force To Mono. - Load In Background. - Preload Audio Data. - Load Type. - Compression Format. - Quality. - Sample Rate. - Filters by MP3, OGG and WAV extensions. Model optimization can enable mesh compression, disable Read/Write and enable optimize mesh, including internal `optimizeMesh`, `optimizeMeshPolygons` and `optimizeMeshVertices` properties when they are available in the current Unity version. Material optimization can change GPU Instancing and, when `Change Shaders` is enabled, replace materials from an old shader name to a new shader name. If the new shader is not found, the optimizer writes an error to the log and leaves the material unchanged. Optimization is applied only after a Unity confirmation dialog. During application PrimeSDK shows a progress bar, changes assets through `AssetDatabase.StartAssetEditing()`, then runs `AssetDatabase.Refresh()`. Recommended workflow: - Make sure required scenes are enabled in Build Settings. - Open `PrimeSDK -> Build Optimizer`. - Configure WebGL build settings and output format on the right side. - Run `Analyze Only` to inspect dependencies and candidates without building. - Configure `Textures`, `Audio`, `Models`, `Materials` steps and deselect assets that should not be changed. - Go to `Apply` and apply selected changes. - Build through `Build & Analyze` and compare final output size. > **Important** > > After optimization, test the game in a browser: UI sharpness, texture readability, audio quality, and correct rendering of models and materials. ## RuStore The RuStore module connects Android RuStore integrations to the common PrimeSDK API. RuStore API for PrimeSDK is intended for Android builds. The package adds providers for payments, platform information, player authorization status and the native app review flow. The module does not add a separate game-facing entry point. After installing the package, game code keeps using the common PrimeSDK API: `PrimeSDK.Payments`, `PrimeSDK.Platform` and `PrimeSDK.Player`. Implemented in the current RuStore module: - `RuStorePayments` - purchases, product catalog loading, purchased product checks and purchase restoration through RuStore Pay. - `RuStorePlatformInfo` - returns `PlatformType.RuStore` and `DeploymentType.Mobile`. - `RuStorePlatformInteractions` - opens the RuStore Review Flow through `PrimeSDK.Platform.RateGame()`. - `RuStorePlayerAccount` - checks RuStore Pay user authorization status and exposes it through the common player API. Current implementation limits: - Android only: the `PrimeGames.SDK.RuStore` assembly is limited to Android. - `PrimeSDK.Platform.ShareGame(...)` is not implemented for RuStore yet. - `PrimeSDK.Platform.AppId` returns the default value because the app id is not read from the RuStore package. - RuStore Pay subscriptions are ignored; product purchases are supported. - Player profile fields such as display name, username and unique id are not filled yet; only authorization status is available. Install `RuStore API for PrimeSDK` from PrimeSDK Package Manager before using it. It pulls RuStore Core, RuStore Pay, RuStore Review and `RuStoreSDKSettings.unitypackage` dependencies. Products are configured in the `RuStorePayments` provider through `ProductsJson`. This JSON contains product tags that must match product ids in the RuStore dashboard. `json { "Values": ["coins_pack_1", "remove_ads", "starter_bundle"] } ` When the provider starts, PrimeSDK checks payment availability with `RuStorePayClient.Instance.GetPurchaseAvailability`, loads products with `GetProducts` and reads purchases with `GetPurchases`. Wait for `PrimeSDK.WaitForProviders(...)` before accessing payments. `csharp using PrimeGames.SDK; using PrimeGames.SDK.Common; using UnityEngine; PrimeSDK.WaitForProviders(() => { ProductData product = PrimeSDK.Payments.GetProductData("coins_pack_1"); Debug.Log($"{product.Tag}: {product.GetFullPriceFloat()}"); }); ` Product purchase uses the common `PrimeSDK.Payments.Purchase(...)` API. Internally the RuStore provider calls `RuStorePayClient.Instance.Purchase(...)` with `PreferredPurchaseType.ONE_STEP`. `csharp PrimeSDK.Payments.Purchase( productTag: "coins_pack_1", onSuccess: () => { GiveProduct("coins_pack_1"); Debug.Log("RuStore purchase completed"); }, onError: () => Debug.Log("RuStore purchase failed") ); ` Purchase restoration also uses the common API. The provider rereads RuStore purchases, compares them with already supplied PrimeSDK products and returns `IRestoreData`. `csharp PrimeSDK.Payments.RestorePurchases((IRestoreData restoreData) => { if (restoreData == null) { return; } foreach (string productTag in restoreData.PendingProducts) { restoreData.RestoreProduct(productTag, () => GiveProduct(productTag)); } }); ` Open the native app review flow through the common platform API: `csharp PrimeSDK.Platform.RateGame(); ` Use the common PrimeSDK API to check the platform: `csharp PlatformType platform = PrimeSDK.Platform.Current; // RuStore DeploymentType deployment = PrimeSDK.Platform.Deployment; // Mobile ` ## Yandex Mobile Ads The Yandex Mobile Ads module connects Yandex mobile advertising to the common PrimeSDK.Ads API. Yandex Mobile Ads API for PrimeSDK is intended for mobile advertising in Android builds. The package adds the `YandexMobileAds` provider for the `IAds` interface; it does not add a separate game-facing API. After installation, game code keeps using the common `PrimeSDK.Ads` API. In Toolkit, open the target Android configuration, go to the `Ads` foldout, enable `Use custom`, and select `YandexMobileAds` as the ads provider. Implemented in the current module: - Interstitial ads through `PrimeSDK.Ads.InvokeInterstitial(...)`. - Rewarded ads through `PrimeSDK.Ads.InvokeRewarded(...)`. - Ads are loaded on show request: the provider creates an `InterstitialAdLoader` or `RewardedAdLoader`, loads the ad and shows it immediately after a successful load. - `onOpen` is called after the `OnAdShown` event. - For interstitial ads, `onClose(true)` is called after `OnAdDismissed`; load or show failures call `onClose(false)`. - For rewarded ads, `onClose(true)` is called only if the Yandex SDK sends `OnRewarded`; otherwise the close result is treated as unsuccessful. Not supported yet: - Banners are not implemented in this provider: `InvokeBanner`, `RefreshBanner` and `DisableBanner` only log warnings. - `rewardTag` is passed through the common PrimeSDK API, but Yandex Mobile Ads does not use it to select an ad block. Block selection uses `RewardedAdUnitIdAndroid` and `RewardedAdUnitIdIOS` configuration fields. - The current asmdef is limited to Android/Editor and `UNITY_ANDROID`; even though iOS fields exist in the configuration, the current PrimeSDK package is Android-oriented. Dependencies are installed from OpenUPM: `com.google.external-dependency-manager` and `com.yandex.mobileads`. If you install the module through PrimeSDK Package Manager, the Toolkit should add these dependencies automatically. For manual installation, add the OpenUPM scoped registry with URL `https://package.openupm.com` and scopes `com.yandex`, `com.google`, then install `External Dependency Manager for Unity`, `Yandex Mobile Ads plugin for Unity`, and this PrimeSDK API package. After installing Yandex Mobile Ads, run `Force Resolve` through External Dependency Manager and make sure dependency resolution succeeds before building for Android. Provider settings: - `Interstitial UID Android` - Android interstitial ad unit id. - `Rewarded UID Android` - Android rewarded ad unit id. - `Interstitial UID iOS` and `Rewarded UID iOS` exist in the configuration class, but the current PrimeSDK package is built as an Android integration. You can use Yandex demo ad unit ids for testing, but do not leave them in production builds. Interstitial example: `csharp using PrimeGames.SDK; using UnityEngine; PrimeSDK.WaitForProviders(() => { if (!PrimeSDK.Ads.IsInterstitialAvailable) { Debug.Log("Yandex interstitial is not available"); return; } PrimeSDK.Ads.InvokeInterstitial( onOpen: () => Debug.Log("Yandex interstitial opened"), onClose: isSuccess => Debug.Log($"Yandex interstitial closed. Success: {isSuccess}") ); }); ` Rewarded example: `csharp PrimeSDK.WaitForProviders(() => { if (!PrimeSDK.Ads.IsRewardedAvailable) { Debug.Log("Yandex rewarded is not available"); return; } PrimeSDK.Ads.InvokeRewarded( onOpen: () => Debug.Log("Yandex rewarded opened"), onClose: isSuccess => { if (isSuccess) { GiveReward(); } Debug.Log($"Yandex rewarded closed. Reward granted: {isSuccess}"); }, rewardTag: "extra_lives" ); }); ` Because ads are loaded when a show call is made, do not bind Yandex Mobile Ads logic to `IsInterstitialReady` or `IsRewardedReady`. For this provider, check `IsInterstitialAvailable` / `IsRewardedAvailable` and handle the final result in `onClose`. ## Platform PrimeSDK.Platform reports the platform and deployment environment where the game is running, and exposes platform actions. Before accessing `PrimeSDK.Platform`, wait for SDK readiness with `PrimeSDK.WaitForProviders(...)`. In the WebGL configuration, `Current` is detected by the PrimeWeb platform layer, `Deployment` usually returns `Web`, and `AppId` comes from the platform if the platform provides an application identifier. Get the platform type, deployment type and unique game identifier on the platform: `csharp using PrimeGames.SDK.Common; PlatformType platform = PrimeSDK.Platform.Current; DeploymentType deployment = PrimeSDK.Platform.Deployment; string appId = PrimeSDK.Platform.AppId; ` `DeploymentType` can be `Unknown`, `Editor`, `Web`, `Mobile`, `Standalone`, `Console`. `PlatformType` contains specific platforms and stores, such as `YandexGames`, `CrazyGames`, `GameDistribution`, `VK`, `OK`, `MSN`, `Xiaomi`, `RuStore`, `GooglePlay`, `Steam` and others. Share the game: `csharp PrimeSDK.Platform.ShareGame("message text"); ` Ask the player to rate the game: `csharp PrimeSDK.Platform.RateGame(); ` Example of platform-specific logic: `csharp using PrimeGames.SDK; using PrimeGames.SDK.Common; using UnityEngine; PrimeSDK.WaitForProviders(() => { PlatformType platform = PrimeSDK.Platform.Current; if (platform == PlatformType.VK || platform == PlatformType.OK) { PrimeSDK.Platform.ShareGame("Try my game!"); } Debug.Log($"Platform: {platform}, deployment: {PrimeSDK.Platform.Deployment}, appId: {PrimeSDK.Platform.AppId}"); }); ` > **Important** > > If the current platform does not support `ShareGame` or `RateGame`, the fallback provider logs a warning without performing any platform action. ## Time PrimeSDK.Time controls time scale and provides the current date and holiday. When integrating PrimeSDK, replace direct `Time.timeScale` usage with `PrimeSDK.Time.Scale`. The SDK uses time scale for pause and resume handling, so direct `Time.timeScale` changes can conflict with system pause, ads or focus loss. `PrimeSDK.Time.Scale` caches the value assigned by the game. When the SDK pauses the game, the actual `Time.timeScale` can temporarily become `0`, and after resume the SDK restores the saved `PrimeSDK.Time.Scale` value. Get and change the time scale: `csharp float timeScale = PrimeSDK.Time.Scale; PrimeSDK.Time.Scale = 1.0f; ` Get the current time as `DateTime`: `csharp using System; DateTime currentDate = PrimeSDK.Time.CurrentDate; ` Get the current holiday: `csharp using PrimeGames.SDK.Common; HolidayType holiday = PrimeSDK.Time.CurrentHoliday; ` In the current API, `HolidayType` can be `None`, `NewYear`, `Halloween`, `Easter`. The default date provider uses local `DateTime.Now`. Example of reacting to a holiday: `csharp using PrimeGames.SDK.Common; if (PrimeSDK.Time.CurrentHoliday == HolidayType.Halloween) { EnableHalloweenTheme(); } void EnableHalloweenTheme() { // Enable holiday assets or events. } `