关于 playgama-bridge-js-sdk
面向 HTML5 游戏的 JavaScript SDK 技能,通过统一 API 支持多个发布平台。它会调用平台原生脚本,并在不支持的环境中使用 mock 平台提供默认响应。
主要功能
- 01跨支持平台的统一 API
- 02自动加载原生平台脚本
- 03不支持环境中的 mock 回退
- 04玩家授权与身份数据
- 05本地或平台存储持久化
- 06插屏、激励和横幅广告
适用场景
- 01将同一 HTML5 构建发布到多个平台
- 02在本地或平台云存储保存进度
- 03处理平台登录和玩家身份
- 04集成广告与生命周期事件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ hungify/ playables-skills --skill playgama-bridge-js-sdk安装后在 Claude Code 中输入/playgama-bridge-js-sdk确认已加载。
详细介绍
Playgama Bridge JS SDK
Playgama Bridge 是一个统一的 JS SDK,可让同一个 HTML5 构建版本在 20 多个平台上运行(Playgama、Yandex Games、Crazy Games、Facebook Gaming、YouTube Playables、Telegram、Poki、Y8、Lagged、MSN、Microsoft Store、Discord、GameSnacks、Xiaomi、Huawei、JioGames、BitQuest、Reddit、Game Distribution、Playhop、Aha Games 等)。
游戏在受支持的平台上运行时,Bridge 会自动加载该平台的原生脚本,并将 API 调用转发给该平台。在不受支持的环境中(本地开发、未知主机),Bridge 会使用 mock 平台返回安全的默认值(false、reject 等),而不会抛出异常——同一份代码可在任何环境中运行。
JS SDK(JS Core)是基础;引擎包(Unity、Godot、Construct、GDevelop、GameMaker、Defold、Cocos Creator、Scratch)则是轻量封装。对于 PlayCanvas、Phaser、LayaAir、Three.js、Babylon.js 等 Web 引擎,请直接使用 JS Core。
安装
在 index.html 的 <head> 中、所有游戏代码之前添加 script 标签:
<html>
<head>
<script src="https://bridge.playgama.com/v1/stable/playgama-bridge.js"></script>
</head>
<body>
...
</body>
</html>
CDN 选项:
| URL | 使用时机 |
|---|---|
https://bridge.playgama.com/v1/stable/playgama-bridge.js | 推荐。 最新稳定版 v1.x.x |
https://bridge.playgama.com/latest/playgama-bridge.js | 前沿版本——仅用于测试 |
https://bridge.playgama.com/v1.27.0/playgama-bridge.js | 固定使用指定版本 |
脚本加载后,SDK 会提供全局 bridge 对象。
配置文件
Bridge 会从构建根目录读取 playgama-bridge-config.json。该文件用于声明平台 ID、IAP 商品目录、广告位、排行榜及其他设置。请使用配置编辑器生成或编辑该文件。
基本结构:
{
"platforms": {
"playgama": { "options": {} },
"yandex": { "options": {} }
},
"advertisement": {
"interstitial": { "minimumDelay": 60 },
"advancedBanners": {/* see Advanced Banners */}
},
"payments": [
{
"id": "coins_100",
"playgama": { "amount": 1 },
"playdeck": { "amount": 1, "description": "100 Coins" }
}
],
"leaderboards": [{ "id": "high_score" }]
}
初始化
调用 bridge.initialize(),并在处理任何其他 API 之前等待其 promise 完成。
bridge
.initialize()
.then(() => {
// SDK is ready, all bridge.* APIs are usable now
})
.catch((error) => {
// Initialization failed — handle gracefully (the SDK still falls back to mock)
});
初始化完成后,在游戏完全加载且玩家可以开始操作时发送 game_ready:
bridge.platform.sendMessage('game_ready');
这会关闭平台加载器。此操作是必需的——否则,大多数平台会一直在游戏画面上方显示启动画面。
必需的集成检查清单
每款游戏都需要:
- 安装 SDK 并创建
playgama-bridge-config.json。 - 等待
bridge.initialize()完成。 - 读取
bridge.platform.language并应用本地化。 - 使用
bridge.storage.get(...)加载已保存的进度。 - 在渲染出第一帧可玩画面后,发送
bridge.platform.sendMessage('game_ready')。 - 响应
AUDIO_STATE_CHANGED和PAUSE_STATE_CHANGED事件。 - 在自然的间歇点(关卡切换、游戏结束、菜单与游戏过程之间切换)展示插屏广告。
插屏广告是收入分成的强制要求。缺少插屏广告的游戏可能会在审核期间被拒绝。
平台模块 — bridge.platform
属性
| 属性 | 类型 | 描述 |
|---|---|---|
bridge.platform.id | string | 当前平台 ID。取值之一:playgama、vk、ok、yandex、facebook、crazy_games、game_distribution、playdeck、telegram、y8、lagged、msn、microsoft_store、poki、qa_tool、discord、gamepush、bitquest、huawei、jio_games、reddit、youtube、mock、xiaomi |
bridge.platform.sdk | object | null | 原生平台 SDK(Bridge 提供时)。仅用于 Bridge 未封装的功能 |
bridge.platform.language | string | 用户语言的 ISO 639-1 代码(en、ru 等)。缺省时使用浏览器语言 |
bridge.platform.payload | string | null | URL 启动载荷(推荐码、深层链接)。格式因平台而异 |
bridge.platform.tld | string | null | 顶级域名(com、ru 等),由主机提供时可用 |
bridge.platform.isAudioEnabled | boolean | 主机平台当前是否允许游戏音频 |
bridge.platform.isGetAllGamesSupported | boolean | getAllGames() 的功能标记 |
bridge.platform.isGetGameByIdSupported | boolean | getGameById() 的功能标记 |
方法
// Server time — UTC ms — use for daily rewards / cooldowns instead of local clock
bridge.platform
.getServerTime()
.then((utcMs) => console.log(utcMs))
.catch((error) => {});
// All games by the same developer (for "More games" screens)
bridge.platform.getAllGames().then((games) => {
// platform-specific shape, on yandex: { appID, title, url, coverURL, iconURL }
});
// One game by ID (cross-promotion)
bridge.platform.getGameById({ gameId: '111111' }).then((game) => {
// { appID, title, url, coverURL, iconURL, isAvailable }
});
// Lifecycle messages — see table below
bridge.platform.sendMessage('game_ready');
// Custom messages — used by Advanced Banners config
bridge.platform.sendCustomMessage('shop_opened');
内置生命周期消息
| 消息 | 载荷 | 发送时机 |
|---|---|---|
game_ready | — | 游戏已加载,加载画面已结束,玩家可以进行交互(必需) |
in_game_loading_started | — | 开始子加载(例如,加载关卡) |
in_game_loading_stopped | — | 子加载结束 |
gameplay_started | — | 开始主动游戏 |
gameplay_stopped | — | 主动游戏结束(菜单、暂停、游戏结束) |
player_got_achievement | — | 发生重要时刻(击败 Boss、创造纪录) |
level_started | { world, level }(可选) | 关卡开始 |
level_completed | { world, level } | 赢得关卡 |
level_failed | { world, level } | 输掉关卡 |
level_paused | { world, level } | 打开暂停菜单 |
level_resumed | { world, level } | 从暂停状态恢复 |
这些消息也会自动触发 Advanced Banners 展示位。
事件
// Audio mute/unmute requests from the host
bridge.platform.on(bridge.EVENT_NAME.AUDIO_STATE_CHANGED, (isEnabled) => {
if (!isEnabled) muteGameAudio();
else restoreGameAudio();
});
// Pause/resume requests (tab switch, platform overlay, etc.)
bridge.platform.on(bridge.EVENT_NAME.PAUSE_STATE_CHANGED, (isPaused) => {
if (isPaused) pauseGame();
else resumeGame();
});
必须处理这两个事件——许多平台会在审核期间强制要求处理。
玩家模块 — bridge.player
玩家身份和平台授权。
| 属性 | 类型 | 描述 |
|---|---|---|
bridge.player.id | string | null | 平台玩家 ID,仅在授权后提供 |
bridge.player.name | string | null | 平台提供的显示名称 |
bridge.player.photos | string[] | 按分辨率从低到高排序的头像 URL;若没有则为 [] |
bridge.player.extra | object | 平台特定的身份验证/验证数据 |
bridge.player.isAuthorizationSupported | boolean | 宿主是否支持登录流程 |
bridge.player.isAuthorized | boolean | 玩家当前是否已授权 |
// Trigger only from a direct user action (button tap)
bridge.player
.authorize({})
.then(() => {
// bridge.player.id, .name, .photos now populated
})
.catch((error) => {
// Cancelled or failed
});
某些平台在授权前也会提供访客数据(name、部分 id)。不要将其视为已验证数据——只有授权后的数据才可信。
后端验证
使用 bridge.player.extra 在你的服务器上验证玩家身份。目前 Playgama 的验证 API 仅支持 playgama、msn 和 microsoft_store:
curl -X POST 'https://playgama.com/api/bridge/v1/verify' \
-H 'Content-Type: application/json' \
-d '{"platform":"<PLATFORM_ID>","type":"authorization","data":{ <...bridge.player.extra> }}'
# Response: { success, errorMessage?, playerId?, publisherPlayerId? }
设备模块 — bridge.device
bridge.device.type; // 'mobile' | 'tablet' | 'desktop' | 'tv'
用于广泛适配 UI,例如触控与键盘输入、资源质量和布局。不要根据设备类型做业务逻辑决策。
存储模块 — bridge.storage
持久化玩家数据(进度、设置、货币)。几乎每款游戏都需要它。
两种存储类型
| 类型 | 持久化方式 | 跨设备 | 适用场景 |
|---|---|---|---|
local_storage | 浏览器 localStorage | 否 | 默认用于离线的单设备存档 |
platform_internal | 平台云服务器 | 是 | 玩家已获授权且需要云同步 |
bridge.storage.defaultType;
// 'local_storage' or 'platform_internal' — host's preferred type
bridge.storage.isAvailable('local_storage');
bridge.storage.isAvailable('platform_internal');
// Check before forcing a specific type
加载
// Single key
bridge.storage.get('level').then((value) => {
// value === null when key is missing — always have a default in your game state
});
// Multiple keys — returns array, same order
bridge.storage.get(['level', 'coins', 'settings']).then(([level, coins, settings]) => {});
// Force specific storage type (third arg)
bridge.storage.get('level', 'local_storage');
保存
bridge.storage.set('level', 'dungeon_3');
bridge.storage
.set(['level', 'coins', 'tutorial_done'], ['dungeon_3', 42, true])
.then(() => {
/* persisted */
})
.catch((error) => {});
bridge.storage.set('level', 'dungeon_3', 'platform_internal');
在有意义的状态变化时保存(关卡完成、购买、设置变更)。不要每帧都保存。
删除
bridge.storage.delete('level');
bridge.storage.delete(['level', 'coins']);
广告模块 — bridge.advertisement
playgama-bridge-config.json 控制广告位。切勿在游戏进行期间展示广告——只在自然停顿时展示。
格式概览
| 格式 | 状态 | 适用时机 |
|---|---|---|
| 插屏广告 | 必需 | 关卡切换、游戏结束、菜单↔游戏进行 |
| 激励广告 | 推荐 | 玩家选择领取游戏内奖励 |
| 横幅广告 | 推荐 | 闲置界面(菜单、大厅、暂停) |
| 高级横幅广告 | 推荐 | 自定义多位置响应式横幅布局 |
| 广告拦截检查 | 可选 | 广告被拦截时调整 UI |
插屏广告 — 必需
bridge.advertisement.isInterstitialSupported; // boolean
bridge.advertisement.minimumDelayBetweenInterstitial; // default 60 seconds
bridge.advertisement.setMinimumDelayBetweenInterstitial(30); // override
bridge.advertisement.interstitialState;
// 'loading' | 'opened' | 'closed' | 'failed'
bridge.advertisement.on(bridge.EVENT_NAME.INTERSTITIAL_STATE_CHANGED, (state) => {
if (state === 'opened') {
muteGameAudio();
pauseGame();
} else if (state === 'closed' || state === 'failed') {
restoreGameAudio();
resumeGame();
}
});
// Optional placement string
bridge.advertisement.showInterstitial('level_complete');
不要在游戏开始时调用 showInterstitial()——支持启动插屏的平台会自动展示。显式调用会导致重复展示广告。
初始化后还要检查 interstitialState:如果它已经是 opened,请立即静音并暂停。
激励广告
bridge.advertisement.isRewardedSupported;
bridge.advertisement.rewardedState;
// 'loading' | 'opened' | 'closed' | 'rewarded' | 'failed'
bridge.advertisement.rewardedPlacement; // current placement string
bridge.advertisement.on(bridge.EVENT_NAME.REWARDED_STATE_CHANGED, (state) => {
switch (state) {
case 'opened':
muteGameAudio();
pauseGame();
break;
case 'rewarded':
// ONLY here grant the reward
grantReward(bridge.advertisement.rewardedPlacement);
break;
case 'closed':
case 'failed':
restoreGameAudio();
resumeGame();
break;
}
});
bridge.advertisement.showRewarded('double_coins');
**重要:**仅在 rewarded 状态时发放奖励。在 closed 时发放会让玩家无需观看广告就能领取奖励。
横幅广告
bridge.advertisement.isBannerSupported;
let position = 'bottom'; // 'top' | 'bottom', default 'bottom'
let placement = 'menu'; // optional
bridge.advertisement.showBanner(position, placement);
bridge.advertisement.hideBanner();
bridge.advertisement.bannerState;
// 'loading' | 'shown' | 'hidden' | 'failed'
bridge.advertisement.on(bridge.EVENT_NAME.BANNER_STATE_CHANGED, (state) => {});
高级横幅广告
由配置驱动的多位置响应式横幅布局。插屏广告/激励广告期间自动隐藏,之后自动恢复。在方向/尺寸变化时重新评估(200ms 防抖)。
bridge.advertisement.isAdvancedBannersSupported;
// Method 1 — explicit
bridge.advertisement.showAdvancedBanners('main_menu');
bridge.advertisement.hideAdvancedBanners();
// Method 2 — automatic via platform messages (recommended)
bridge.platform.sendMessage('gameplay_stopped'); // shows if configured
bridge.platform.sendMessage('gameplay_started'); // hides if action: 'hide'
bridge.platform.sendCustomMessage('shop_opened');
// State
bridge.advertisement.advancedBannersState;
bridge.advertisement.on('advanced_banners_state_changed', (state) => {});
配置示例:
{
"advertisement": {
"advancedBanners": {
"disable": false,
"placementFallback": "main_menu",
"main_menu": {
"default": [{ "width": "20%", "height": "25%", "top": "10%", "right": "10%" }]
},
"gameplay_stopped": {
"action": "show",
"default": [{ "width": "20%", "height": "25%", "bottom": "10%", "right": "5%" }],
"mobile:portrait": [
{ "width": "100%", "height": "8%", "bottom": "0", "left": "0" }
],
"desktop:landscape:w>1200": [
{ "width": "10%", "height": "60%", "top": "10%", "left": "1%" },
{ "width": "10%", "height": "60%", "top": "10%", "right": "1%" }
]
},
"gameplay_started": { "action": "hide" }
}
}
}
条件键
以冒号分隔的字段,必须全部匹配:
| 字段 | 示例 |
|---|---|
| 设备类型 | mobile、desktop、tablet、tv |
| 方向 | portrait、landscape |
| 宽度 | w>600、w<=1024、w>=768 |
| 高度 | h>400、h<=900 |
| 宽高比 | ar>1.5、ar>=1.78、ar<=1.0 |
| 画布模式 | canvas(使用画布尺寸而非窗口尺寸) |
优先级:设备类型 +4,方向 +2,画布 +1,每个 w/h/ar 条件 +1。优先级相同时,字段更多者优先 → 阈值更接近实际值者优先。default 为回退项(-1)。
横幅对象
CSS 定位:width、height、top、bottom、left、right——全部为字符串("300px"、"100%"、"0")。
广告拦截检测
bridge.advertisement.checkAdBlock().then((isBlocked) => {
// true | false — informational only, doesn't suppress ads
});
支付模块 — bridge.payments
游戏内购买。可选,但通常是收入最高的功能。
产品类型
| 类型 | 示例 | 生命周期 |
|---|---|---|
| 永久性 | “移除广告”、DLC | 一次购买。每次启动时使用 getPurchases() 检查所有权 |
| 消耗型 | 金币、宝石、能量 | 购买 → 发放 → 必须使用 consumePurchase(id) 消耗。在消耗之前,无法再次购买同一产品 |
API
bridge.payments.isSupported;
// Catalog — localized prices, currencies, metadata
bridge.payments.getCatalog().then((items) => {
items.forEach((item) => {
console.log(item.id);
console.log(item.price); // formatted string
console.log(item.priceCurrencyCode); // ISO 4217
console.log(item.priceValue); // numeric value
});
});
// Purchase — only from a direct user action
bridge.payments
.purchase('coins_100')
.then((purchase) => {
// Platform-specific shape, always has .id
grantItems(purchase.id);
// For consumables, immediately consume:
return bridge.payments.consumePurchase(purchase.id);
})
.catch((error) => {
// Cancelled or failed
});
// Consume a consumable after granting items
bridge.payments.consumePurchase('coins_100').then((purchase) => {});
// Active purchases — call on every launch and after reconnect
// to recover items from purchases interrupted by disconnects
bridge.payments.getPurchases().then((purchases) => {
purchases.forEach((p) => {
// Permanent: check ownership here
// Consumable: grant items + consume
});
});
目录配置
{
"payments": [
{
"id": "coins_100",
"playgama": { "amount": 1 },
"playdeck": { "amount": 1, "description": "100 Coins" }
}
]
}
id 是游戏内标识符;各平台键包含特定平台的价格/元数据。
后端验证
curl -X POST 'https://playgama.com/api/bridge/v1/verify' \
-H 'Content-Type: application/json' \
-d '{"platform":"<PLATFORM_ID>","type":"purchase","data":{ <...purchase> }}'
# Response: { success, errorMessage?, orderId?, productId?, externalId? }
目前支持 playgama、msn、microsoft_store。
排行榜模块 — bridge.leaderboards
可选。首先检查 bridge.leaderboards.type:
| 类型 | 操作 |
|---|---|
not_available | 隐藏所有排行榜 UI |
in_game | 调用 setScore(...),使用 getEntries(...) 渲染自己的 UI |
native | 仅调用 setScore(...) — 由平台显示排行榜 |
native_popup | 调用 setScore(...) 和 showNativePopup(...) 打开浮层 |
API
bridge.leaderboards.type;
bridge.leaderboards.setScore('high_score', 1000).then(() => {});
// Only when type === 'in_game'
bridge.leaderboards.getEntries('high_score').then((entries) => {
entries.forEach((e) => {
console.log(e.id);
console.log(e.name);
console.log(e.photo);
console.log(e.score);
console.log(e.rank);
});
});
// Only when type === 'native_popup'
bridge.leaderboards.showNativePopup('high_score');
配置
{
"leaderboards": [
{
"id": "high_score",
"<PLATFORM_ID>": "<NATIVE_ID_FOR_PLATFORM>"
}
]
}
在代码中使用游戏内的 id;当各平台的原生排行榜 ID 不同时,平台覆盖项会映射到对应的 ID。
成就模块 — bridge.achievements
可选。成就 ID 配置在各平台的开发者控制面板中,而不是 playgama-bridge-config.json 中。
bridge.achievements.isSupported;
bridge.achievements.isGetListSupported;
bridge.achievements.isNativePopupSupported;
// Unlock — send each achievement only once
let options = {};
switch (bridge.platform.id) {
case 'y8':
options = { achievement: 'ACHIEVEMENT_NAME', achievementkey: 'ACHIEVEMENT_KEY' };
break;
case 'lagged':
options = { achievement: 'ACHIEVEMENT_ID' };
break;
}
bridge.achievements.unlock(options).then(() => {});
// List (platform-specific shape)
bridge.achievements.getList({}).then((list) => {});
// Native overlay
bridge.achievements.showNativePopup({});
在游戏中保留一个常量文件,将内部里程碑映射到各平台的成就 ID。
社交模块 — bridge.social
所有功能均为可选。每个方法都有一个 is*Supported 标志——务必检查该标志,不支持时隐藏按钮。仅在用户直接操作时触发。
功能支持矩阵
| 功能 | 标志 | 常见平台 |
|---|---|---|
| 分享 | isShareSupported | VK、Facebook、MSN |
| 加入社区 | isJoinCommunitySupported | VK、OK、Facebook |
| 邀请好友 | isInviteFriendsSupported | VK、OK、Facebook |
| 创建帖子 | isCreatePostSupported | VK、OK |
| 添加到收藏 | isAddToFavoritesSupported | VK、Yandex |
| 添加到主屏幕 | isAddToHomeScreenSupported | Yandex、GameSnacks |
| 为游戏评分 | isRateSupported | VK、GameSnacks、Yandex |
| 外部链接 | isExternalLinksAllowed | 大多数非门户平台 |
分享
let options = {};
switch (bridge.platform.id) {
case 'vk':
options = { link: 'https://...' };
break;
case 'facebook':
options = { image: 'base64...', text: 'Check this game!' };
break;
case 'msn':
options = { title: '...', image: 'base64 or URL', text: '...' };
break;
}
bridge.social.share(options).then(() => {});
加入社区
let options = {};
switch (bridge.platform.id) {
case 'vk':
case 'ok':
options = { groupId: 123456 };
break;
case 'facebook':
options = { isPage: true };
break; // false → group
}
bridge.social.joinCommunity(options);
邀请好友
let options = {};
switch (bridge.platform.id) {
case 'ok':
options = { text: 'Hello!' };
break;
case 'facebook':
options = { image: 'base64...', text: 'Join me!' };
break;
}
bridge.social.inviteFriends(options);
创建帖子
// OK example with mixed media
bridge.social.createPost({
media: [
{ type: 'text', text: 'Hello!' },
{ type: 'link', url: 'https://...' },
{
type: 'poll',
question: 'Like the game?',
answers: [{ text: 'Yes' }, { text: 'No' }],
options: 'SingleChoice,AnonymousVoting'
}
]
});
其他社交功能
bridge.social.addToFavorites().then(() => {});
bridge.social.addToHomeScreen().then(() => {});
bridge.social.rate().then(() => {});
远程配置模块 — bridge.remoteConfig
可选。无需重新构建,即可在运行时读取游戏设置(难度、掉落率、功能标志、A/B 测试值)。
bridge.remoteConfig.isSupported;
let options = {};
switch (bridge.platform.id) {
case 'yandex':
options = {
clientFeatures: [{ name: 'levels', value: '5' }]
};
break;
}
bridge.remoteConfig
.get(options)
.then((data) => {
// e.g. { showFullscreenAdOnStart: 'no', difficulty: 'hard' }
})
.catch((error) => {});
务必为每个键设置硬编码默认值。请求可能失败或仅返回部分数据。
事件名称
bridge.EVENT_NAME.AUDIO_STATE_CHANGED;
bridge.EVENT_NAME.PAUSE_STATE_CHANGED;
bridge.EVENT_NAME.INTERSTITIAL_STATE_CHANGED;
bridge.EVENT_NAME.REWARDED_STATE_CHANGED;
bridge.EVENT_NAME.BANNER_STATE_CHANGED;
bridge.EVENT_NAME.ADVANCED_BANNERS_STATE_CHANGED;
bridge.platform.on(...) 和 bridge.advertisement.on(...) 也接受事件名称字符串。
状态值参考
| 模块 | 状态 |
|---|---|
| 插屏广告 | loading、opened、closed、failed |
| 激励广告 | loading、opened、closed、rewarded、failed |
| 横幅广告 | loading、shown、hidden、failed |
| 高级横幅 | loading、shown、hidden、failed |
| 排行榜类型 | not_available、in_game、native、native_popup |
| 存储类型 | local_storage、platform_internal |
最佳实践清单
- 等待
bridge.initialize()完成后再使用任何 API。 - 使用
bridge.platform.language进行本地化。 - 在展示游戏内容前,通过
bridge.storage.get(...)加载已保存的状态。 - 渲染出首个可玩画面时,发送
bridge.platform.sendMessage('game_ready')。 - 订阅
AUDIO_STATE_CHANGED和PAUSE_STATE_CHANGED,并立即响应。 - 在自然的间歇处展示插屏广告——绝不要在游戏过程中展示。
- 绝不要在游戏开始时调用
showInterstitial()。 - 收到
opened时静音并暂停;收到closed/failed/rewarded时恢复。 - 仅在
rewarded状态下发放奖励。 - 在有意义的事件发生时保存存储数据,而不是每帧都保存。
- 为消耗型购买发放物品后,调用
consumePurchase(id)。 - 在启动和重新连接时,调用
getPurchases()以恢复中断的购买。 - 检查每个
is*Supported标志,并隐藏不受支持功能对应的 UI。 - 仅在用户直接操作时触发社交操作和
payments.purchase()。 - 为每个 Remote Config 键提供硬编码的默认值。
- 发送平台消息(
level_started、gameplay_stopped等)——它们会驱动分析和 Advanced Banners。
本地开发
在 Bridge 无法识别的环境中,它会回退到 mock。API 会返回安全的默认值,而不会抛出错误,因此你可以在发布前进行本地开发和调试。bridge.platform.id === 'mock' 表示处于此状态。
资源
- 配置编辑器:
https://playgama.github.io/bridge-config-editor/ - Wiki:
https://wiki.playgama.com/