JS Core
Внимание!
Данная документация является устаревшей. Instant Games Bridge теперь называется Playgama Bridge. Актуальная документация доступна по ссылке wiki.playgama.com.

JS Core #

JS Core — это сердце SDK, содержит всю основную логику. Плагины под игровые движки (Unity, Godot, Construct) являются лишь надстройкой над JS Core. JS Core можно использовать напрямую без каких-либо плагинов в веб-движках (PlayCanvas, PixiJS, Phaser и т.д.).

Подключение #

Скачайте файл instant-games-bridge.js со страницы релизов на гитхаб, добавьте в свой проект и подключите в index.html:

<html>
    <head>
        <script src="./instant-games-bridge.js"></script>
    </head>
    <body>...</body>
</html>

При запуске игры на поддерживаемых платформах SDK автоматически подключит нужные скрипты платформ. На неподдерживаемой платформе не будет каких-либо ошибок, подставится платформа-заглушка mock и при вызове какого-либо запроса будет возвращаться false, reject и т.д.

Инициализация #

Перед использованием SDK нужно вызвать метод инициализации и дождаться его завершения.

<html>
    <head>...</head>
    <body>...</body>
    <script>
        // простой вариант инициализации
        bridge.initialize()
            .then(() => {
                // инициализация прошла успешно, можно использовать SDK
            })
            .catch(error => {
                // ошибка, что-то пошло не так
            })

        // второй вариант инициализации с передачей дополнительных настроек
        let options = {
            // если присутствует данный параметр, то автоопределение платформы пропустится
            // и бридж подключит SDK указанной платформы
            forciblySetPlatformId: 'yandex',

            platforms: {
                // если вы выпускаете игру на Game Distribution, то необходимо указать её айди
                'game_distribution': { 
                    gameId: 'YOUR_ID_HERE'
                },
                // если вы выпускаете игру в VK Play, то необходимо указать её айди
                'vk_play': { 
                    gameId: 'YOUR_ID_HERE'
                },
                // если вы выпускаете игру в Telegram и используете Adsgram.ai для рекламы
                'telegram': { 
                    adsgramBlockId: 'YOUR_ID_HERE'
                }
            } 
        }
        bridge.initialize(options)
            .then(() => {
                // инициализация прошла успешно, можно использовать SDK
            })
            .catch(error => {
                // ошибка, что-то пошло не так
            })
    </script>
</html>

Информация о платформе #

ID платформы #

bridge.platform.id
Возвращает ID платформы, на которой запущена игра в данный момент. Возможные значения: playgama, crazy_games, game_distribution, yandex, wortal, playdeck, telegram, vk, ok, vk_play, absolute_games, mock.

Нативный SDK #

bridge.platform.sdk

Возвращает нативный SDK платформы.

Платформа Содержание
Playgama Playgama SDK
Crazy Games Crazy Games SDK
Game Distribution Game Distribution SDK
Yandex Yandex Games SDK
Wortal Wortal SDK
PlayDeck null
Telegram Telegram Mini Apps
VK Play VK Play SDK
VK VK Bridge
OK OK SDK
Absolute Games Absolute Games SDK
Mock null

Язык #

bridge.platform.language

Если платформа предоставляет данные об языке пользователя — то это будет язык, который установлен у пользователя на платформе. Если не предоставляет — это будет язык браузера пользователя.

Формат: ISO 639-1. Пример: ru, en.

Параметр из адресной строки #

bridge.platform.payload

С помощью данного параметра можно в ссылку на игру встраивать какую-либо вспомогательную информацию.

Платформа Формат ссылки
Playgama
Crazy Games crazygames.com/game/example?payload=your-info
Game Distribution
Yandex yandex.com/games/play/183100?payload=your-info
Wortal
PlayDeck
Telegram
VK Play
VK vk.com/app8056947#your-info
OK
Absolute Games
Mock site.com/game?payload=your-info

Информация о домене #

bridge.platform.tld
Если данных нет – null. Если данные есть – com, ru, etc.

Отправка сообщения платформе #

bridge.platform.sendMessage('game_ready')
Сообщение Описание
game_ready Игра загрузилась, все загрузочные экраны прошли, игрок может взаимодействовать с игрой.
in_game_loading_started Началась какая-либо загрузка внутри игры. Например, когда идёт загрузка уровня.
in_game_loading_stopped Загрузка внутри игры окончена.
gameplay_started Начался геймплей. Например, игрок зашёл в уровень с главного меню.
gameplay_stopped Геймплей закончился/приостановился. Например, при выходе с уровня в главное меню, открытии меню паузы и т.д.
player_got_achievement Игрок достиг особенного момента. Например, победил босса, установил рекорд и т.д.

Серверное время #

bridge.platform.getServerTime()
    .then(result => {
        console.log(result) // UTC time in milliseconds
    })
    .catch(error => {
        console.log(error)
    })

Информация о девайсе #

Тип девайса #

bridge.device.type
Возвращает тип девайса, с которого пользователь запустил игру. Возможные значения: mobile, tablet, desktop, tv.

Информация об игроке #

Поддержка авторизации #

bridge.player.isAuthorizationSupported
Возможные значения: true, false.

Авторизован ли игрок в данный момент #

bridge.player.isAuthorized
Возможные значения: true, false.

ID игрока #

bridge.player.id
Если данных нет – null. Если данные есть – данные в формате string.

Имя игрока #

bridge.player.name
Если данных нет – null. Если данные есть – данные в формате string.

Аватар игрока #

bridge.player.photos
Возможные значения: пустой массив, массив с ссылками на изображения.

Авторизация игрока #

let options = { }

switch (bridge.platform.id) {
    case 'yandex':
        options = {
            scopes: true  // запросить у игрока доступ к имени и фото
        }
        break
}

bridge.player.authorize(options)
    .then(() => {
        // игрок успешно авторизован
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

Информация об игре #

Текущее состояние видимости #

bridge.game.visibilityState

// Отслеживать изменение состояния можно подписавшись на событие
bridge.game.on(bridge.EVENT_NAME.VISIBILITY_STATE_CHANGED, state => { console.log('Visibility state:', state) })

Возвращает текущее состояние видимости игры (вкладки с игрой). Возможные значения: visible, hidden.

📝 Примечание
Нужно реагировать на изменение состояния видимости. Например, выключать звук в игре при hidden и включать при visible.

Пользовательские данные #

Есть два типа хранилища: локальное local_storage и внутреннее platform_internal. При записи в локальное — данные сохраняются у игрока на конкретном девайсе, при записи во внутреннее — данные сохраняются на серверах платформы.

Текущий тип хранилища #

bridge.storage.defaultType
Тип хранилища, который используется по-умолчанию в конкретный момент на конкретной платформе. Возможные значения: local_storage, platform_internal.

Проверка на поддержку #

bridge.storage.isSupported(bridge.STORAGE_TYPE.LOCAL_STORAGE)
bridge.storage.isSupported(bridge.STORAGE_TYPE.PLATFORM_INTERNAL)
Возможные значения: true, false.

Проверка на доступность #

bridge.storage.isAvailable(bridge.STORAGE_TYPE.LOCAL_STORAGE)
bridge.storage.isAvailable(bridge.STORAGE_TYPE.PLATFORM_INTERNAL)
Возможные значения: true, false.

Загрузка данных #

// загрузить данные по ключу
bridge.storage.get('key')
    .then(data => {
        // данные загружены и вы можете работать с ними
        // data = null если для такого ключа нет данных
        console.log('Data: ', data)
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

// загрузить данные по нескольким ключам
bridge.storage.get(['key_1', 'key2'])
    .then(data => {
        // данные загружены и вы можете работать с ними
        // data[n] = null если для такого ключа нет данных
        console.log('Data: ', data)
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

Сохранение данных #

// сохранить данные по ключу
bridge.storage.set('key', 'value')
    .then(() => {
        // данные успешно сохранены
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

// сохранить данные по нескольким ключам
bridge.storage.set(['key_1', 'key2'], ['value_1', 'value_2'])
    .then(() => {
        // данные успешно сохранены
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

Удаление данных #

// удалить данные по ключу
bridge.storage.delete('key')
    .then(() => {
        // данные успешно удалены
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })
    
// удалить данные по нескольким ключам
bridge.storage.delete(['key_1', 'key2'])
    .then(() => {
        // данные успешно удалены
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

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

let storageType = bridge.STORAGE_TYPE.LOCAL_STORAGE
bridge.storage.get('key', storageType)
bridge.storage.set('key', 'value', storageType)
bridge.storage.delete('key', storageType)
bridge.advertisement.isBannerSupported
Возможные значения: true, false.
let options = { }

switch (bridge.platform.id) {
    case 'vk': 
        options = {
            position: 'top', // необязательный параметр, по умолчанию = bottom
            layoutType: 'resize', // необязательный параметр
            canClose = false // необязательный параметр
        }
        break
    case 'crazy_games': 
        options = {
            containerId: 'div-container-id'
        }
        break
    case 'game_distribution':
        options = {
            containerId: 'div-container-id'
        }
        break
}

bridge.advertisement.showBanner(options)
📝 Примечание
Чтобы баннеры работали в Crazy Games — необходимо в index.html добавить контейнер <div> нужных размеров и передать его идентификатор в showBanner(). Подробнее про размеры: https://docs.crazygames.com/sdk/html5/#responsive-banners.
📝 Примечание
Чтобы баннеры работали в Game Distribution — необходимо в index.html добавить контейнер <div> нужных размеров и передать его идентификатор в showBanner(). Подробнее про размеры: https://github.com/GameDistribution/GD-HTML5/wiki/Display-Ads.
bridge.advertisement.hideBanner()
bridge.advertisement.bannerState

// отслеживать изменение состояния можно подписавшись на событие
bridge.advertisement.on(bridge.EVENT_NAME.BANNER_STATE_CHANGED, state => console.log('Banner state: ', state))
Текущее состояние баннера. Возможные значения: loading, shown, hidden, failed. Межстраничная реклама. Обычно показывается в момент загрузки уровня/поражения и т.д.
// значение по умолчанию = 60 секунд
bridge.advertisement.minimumDelayBetweenInterstitial
Между показами Interstitial-рекламы нужно соблюдать временные интервалы. Например, Yandex просто не покажет рекламу если вызывать слишком часто, а VK будет показывать так часто, как вызывается метод. Для удобства, в данном SDK есть встроенный механизм таймера между показами. Вам нужно лишь указать нужный интервал и можно дёргать метод показа рекламы сколько угодно.
let seconds = 120
bridge.advertisement.setMinimumDelayBetweenInterstitial(seconds)
bridge.advertisement.interstitialState

// отслеживать изменение состояния можно подписавшись на событие
bridge.advertisement.on(bridge.EVENT_NAME.INTERSTITIAL_STATE_CHANGED, state => console.log('Interstitial state: ', state))

Текущее состояние рекламы. Возможные значения: loading, opened, closed, failed.

📝 Примечание
Нужно реагировать на изменение состояния рекламы. Например, выключать звук в игре при opened и включать при closed и failed.
bridge.advertisement.showInterstitial()
Реклама за вознаграждение.
bridge.advertisement.rewardedState

// отслеживать изменение состояния можно подписавшись на событие
bridge.advertisement.on(bridge.EVENT_NAME.REWARDED_STATE_CHANGED, state => console.log('Rewarded state: ', state))

Текущее состояние рекламы. Возможные значения: loading, opened, closed, rewarded, failed.

📝 Примечание
Нужно реагировать на изменение состояния рекламы. Например, выключать звук в игре при opened и включать при closed и failed.
⚠️ Предупреждение
Награду игроку нужно выдавать только при наступлении состояния rewarded.
bridge.advertisement.showRewarded()
Проверить включен ли блокировщик рекламы.
bridge.advertisement.checkAdBlock()
    .then(result => {
        console.log(result) // true or false
    })
    .catch(error => {
        console.log(error)
    })

Социальные взаимодействия #

Поделиться #

bridge.social.isShareSupported

Поддерживается ли функционал на платформе. Возможные значения: true, false.

let options = { }

switch (bridge.platform.id) {
    case 'vk':
        options = {
            link: 'https://vk.com/mewton.games'
        }
        break
}

bridge.social.share(options)
    .then(() => {
        // игрок успешно поделился
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

Вступить в сообщество #

bridge.social.isJoinCommunitySupported

Поддерживается ли функционал на платформе. Возможные значения: true, false.

let options = { }

switch (bridge.platform.id) {
    case 'vk':
        options = {
            groupId: '199747461'
        }
        break
    case 'ok':
        options = {
            groupId: '62984239710374'
        }
        break
}

bridge.social.joinCommunity(options)
    .then(() => {
        // игрок успешно вступил
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

Пригласить друзей #

bridge.social.isInviteFriendsSupported

Поддерживается ли функционал на платформе. Возможные значения: true, false.

let options = { }

switch (bridge.platform.id) {
    case 'ok':
        options = {
            text: 'Hello World!'
        }
        break
}

bridge.social.inviteFriends(options)
    .then(() => {
        // игрок успешно пригласил друзей
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

Опубликовать пост #

bridge.social.isCreatePostSupported

Поддерживается ли функционал на платформе. Возможные значения: true, false.

let options = { }

switch (bridge.platform.id) {
    case 'vk':
        options = {
            message: 'Hello world!',
            attachments: 'photo-199747461_457239629'
        }
        break
    case 'ok':
        options = {
            media: [
                {
                    'type': 'text',
                    'text': 'Hello World!'
                },
                {
                    'type': 'link',
                    'url': 'https://apiok.ru'
                },
                {
                    'type': 'poll',
                    'question': 'Do you like our API?',
                    'answers': [
                        { 'text': 'Yes' },
                        { 'text': 'No' }
                    ],
                    'options': 'SingleChoice,AnonymousVoting'
                }
            ]
        }
        break
}

bridge.social.createPost(options)
    .then(() => {
        // игрок успешно опубликовал пост
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

Добавить в избранное #

bridge.social.isAddToFavoritesSupported

Поддерживается ли функционал на платформе. Возможные значения: true, false.

bridge.social.addToFavorites()
    .then(() => {
        // игрок успешно добавил игру в избранное
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

Добавить на рабочий стол #

bridge.social.isAddToHomeScreenSupported

Поддерживается ли функционал на платформе. Возможные значения: true, false.

bridge.social.addToHomeScreen()
    .then(() => {
        // игрок успешно добавил игру на рабочий стол
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

Оценить игру #

bridge.social.isRateSupported

Поддерживается ли функционал на платформе. Возможные значения: true, false.

bridge.social.rate()
    .then(() => {
        // игрок успешно оценил игру
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })
bridge.social.isExternalLinksAllowed

Разрешены ли внешние ссылки на платформе. Возможные значения: true, false.

Лидерборды #

Поддержка #

bridge.leaderboard.isSupported
Возможные значения: true, false.

Нативный popup #

bridge.leaderboard.isNativePopupSupported

Поддерживается ли нативный popup. Возможные значения: true, false.

// показать нативный popup
let options = { }

switch (bridge.platform.id) {
    case 'vk':
        options = {
            userResult: 42,
            global: true // по умолчанию = false
        }
        break
}

bridge.leaderboard.showNativePopup(options)
    .then(() => {
        // popup успешно показан
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

Очки игрока #

Запись #

bridge.leaderboard.isSetScoreSupported

Поддерживается ли запись очков игрока. Возможные значения: true, false.

let options = { }

switch (bridge.platform.id) {
    case 'yandex':
        options = {
            leaderboardName: 'YOU_LEADERBOARD_NAME',
            score: 42
        }
        break
}

bridge.leaderboard.setScore(options)
    .then(() => {
        // очки успешно записаны
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

Чтение #

bridge.leaderboard.isGetScoreSupported

Поддерживается ли чтение очков игрока. Возможные значения: true, false.

let options = { }

switch (bridge.platform.id) {
    case 'yandex':
        options = {
            leaderboardName: 'YOU_LEADERBOARD_NAME',
        }
        break
}

bridge.leaderboard.getScore(options)
    .then(score => {
        console.log('Score: ' + score)
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

Записи таблицы #

bridge.leaderboard.isGetEntriesSupported

Поддерживается ли чтение полной таблицы. Возможные значения: true, false.

let options = { }

switch (bridge.platform.id) {
    case 'yandex':
        options = {
            leaderboardName: 'YOU_LEADERBOARD_NAME',
            includeUser: true, // по умолчанию = false
            quantityAround: 10, // по умолчанию = 5
            quantityTop: 10 // по умолчанию = 5
        }
        break
}

bridge.leaderboard.getEntries(options)
    .then(entries => {
        // данные успешно получены
        switch (bridge.platform.id) {
            case 'yandex':
                entries.forEach(entry => {
                    console.log('ID: ' + entry.id)
                    console.log('Name: ' + entry.name)
                    console.log('Photo: ' + entry.photo)
                    console.log('Score: ' + entry.score)
                    console.log('Rank: ' + entry.rank)
                })
                break
        }
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

Внутриигровые покупки #

Существуют два типа покупок — постоянные (например, отключение рекламы) и расходуемые (например, внутриигровые монеты).

Поддержка #

bridge.payments.isSupported
Возможные значения: true, false.

Покупка #

let options = { }

switch (bridge.platform.id) {
    case 'yandex':
        options = {
            id: 'PURCHASE_ID' // ID покупки который указан в настройках игры
        }
        break
}

bridge.payments.purchase(options)
    .then(() => {
        // игрок успешно купил
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

Расходование #

let options = { }

switch (bridge.platform.id) {
    case 'yandex':
        options = {
            purchaseToken: 'PURCHASE_TOKEN' // токен купленной покупки
        }
        break
}

bridge.payments.consumePurchase(options)
    .then(() => {
        // покупка успешно израсходована и не будет выведена при вызове getPurchases
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

Каталог всех товаров #

bridge.payments.getCatalog()
    .then(catalogItems => {
        // данные успешно получены
        switch (bridge.platform.id) {
            case 'yandex':
                catalogItems.forEach(catalogItem => {
                    console.log('ID: ' + catalogItem.id)
                    console.log('Title: ' + catalogItem.title)
                    console.log('Description: ' + catalogItem.description)
                    console.log('Image URI: ' + catalogItem.imageURI)
                    console.log('Price: ' + catalogItem.price)
                    console.log('Price Currency Code: ' + catalogItem.priceCurrencyCode)
                    console.log('Price Currency Image: ' + catalogItem.priceCurrencyImage)
                    console.log('Price Value: ' + catalogItem.priceValue)
                })
                break
        }
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

Список купленных товаров #

bridge.payments.getPurchases()
    .then(purchases => {
        // данные успешно получены
        switch (bridge.platform.id) {
            case 'yandex':
                purchases.forEach(purchase => {
                    console.log('Product ID: ' + purchase.productID)
                    console.log('Purchase Token: ' + purchase.purchaseToken)
                })
                break
        }
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })

Удаленная конфигурация #

С помощью удаленной конфигурации вы можете управлять настройками вашей игры не выпуская обновлений.

Поддержка #

bridge.remoteConfig.isSupported
Возможные значения: true, false.

Загрузка значений #

let options = { }

switch (bridge.platform.id) {
    case 'yandex':
        options = {
            clientFeatures: [ // необязательный параметр
                { name: 'levels', value: '5' }
            ]
        }
        break
}

bridge.remoteConfig.get(options)
    .then(data => {
        // data содержит объект ключ-значение, которые указаны в настройках игры
        // например: { showFullscreenAdOnStart: 'no', difficult: 'hard' }
    })
    .catch(error => {
        // ошибка, что-то пошло не так
    })
← Введение Construct →