mcpField
P
playgama-bridge-js-sdk

playgama-bridge-js-sdk

github.com/hungify开发016 次安装1 周前更新
代码仓库

关于 playgama-bridge-js-sdk

面向 HTML5 游戏的 JavaScript SDK 技能,通过统一 API 支持多个发布平台。它会调用平台原生脚本,并在不支持的环境中使用 mock 平台提供默认响应。

主要功能

  1. 01跨支持平台的统一 API
  2. 02自动加载原生平台脚本
  3. 03不支持环境中的 mock 回退
  4. 04玩家授权与身份数据
  5. 05本地或平台存储持久化
  6. 06插屏、激励和横幅广告

适用场景

  1. 01将同一 HTML5 构建发布到多个平台
  2. 02在本地或平台云存储保存进度
  3. 03处理平台登录和玩家身份
  4. 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');

这会关闭平台加载器。此操作是必需的——否则,大多数平台会一直在游戏画面上方显示启动画面。

必需的集成检查清单

每款游戏都需要:

  1. 安装 SDK 并创建 playgama-bridge-config.json。
  2. 等待 bridge.initialize() 完成。
  3. 读取 bridge.platform.language 并应用本地化。
  4. 使用 bridge.storage.get(...) 加载已保存的进度。
  5. 在渲染出第一帧可玩画面后,发送 bridge.platform.sendMessage('game_ready')。
  6. 响应 AUDIO_STATE_CHANGED 和 PAUSE_STATE_CHANGED 事件。
  7. 在自然的间歇点(关卡切换、游戏结束、菜单与游戏过程之间切换)展示插屏广告。

插屏广告是收入分成的强制要求。缺少插屏广告的游戏可能会在审核期间被拒绝。

平台模块 — bridge.platform

属性
属性类型描述
bridge.platform.idstring当前平台 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.sdkobject | null原生平台 SDK(Bridge 提供时)。仅用于 Bridge 未封装的功能
bridge.platform.languagestring用户语言的 ISO 639-1 代码(en、ru 等)。缺省时使用浏览器语言
bridge.platform.payloadstring | nullURL 启动载荷(推荐码、深层链接)。格式因平台而异
bridge.platform.tldstring | null顶级域名(com、ru 等),由主机提供时可用
bridge.platform.isAudioEnabledboolean主机平台当前是否允许游戏音频
bridge.platform.isGetAllGamesSupportedbooleangetAllGames() 的功能标记
bridge.platform.isGetGameByIdSupportedbooleangetGameById() 的功能标记
方法
// 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.idstring | null平台玩家 ID,仅在授权后提供
bridge.player.namestring | null平台提供的显示名称
bridge.player.photosstring[]按分辨率从低到高排序的头像 URL;若没有则为 []
bridge.player.extraobject平台特定的身份验证/验证数据
bridge.player.isAuthorizationSupportedboolean宿主是否支持登录流程
bridge.player.isAuthorizedboolean玩家当前是否已授权
// 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 标志——务必检查该标志,不支持时隐藏按钮。仅在用户直接操作时触发。

功能支持矩阵
功能标志常见平台
分享isShareSupportedVK、Facebook、MSN
加入社区isJoinCommunitySupportedVK、OK、Facebook
邀请好友isInviteFriendsSupportedVK、OK、Facebook
创建帖子isCreatePostSupportedVK、OK
添加到收藏isAddToFavoritesSupportedVK、Yandex
添加到主屏幕isAddToHomeScreenSupportedYandex、GameSnacks
为游戏评分isRateSupportedVK、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

最佳实践清单

  1. 等待 bridge.initialize() 完成后再使用任何 API。
  2. 使用 bridge.platform.language 进行本地化。
  3. 在展示游戏内容前,通过 bridge.storage.get(...) 加载已保存的状态。
  4. 渲染出首个可玩画面时,发送 bridge.platform.sendMessage('game_ready')。
  5. 订阅 AUDIO_STATE_CHANGED 和 PAUSE_STATE_CHANGED,并立即响应。
  6. 在自然的间歇处展示插屏广告——绝不要在游戏过程中展示。
  7. 绝不要在游戏开始时调用 showInterstitial()。
  8. 收到 opened 时静音并暂停;收到 closed/failed/rewarded 时恢复。
  9. 仅在 rewarded 状态下发放奖励。
  10. 在有意义的事件发生时保存存储数据,而不是每帧都保存。
  11. 为消耗型购买发放物品后,调用 consumePurchase(id)。
  12. 在启动和重新连接时,调用 getPurchases() 以恢复中断的购买。
  13. 检查每个 is*Supported 标志,并隐藏不受支持功能对应的 UI。
  14. 仅在用户直接操作时触发社交操作和 payments.purchase()。
  15. 为每个 Remote Config 键提供硬编码的默认值。
  16. 发送平台消息(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/

评论

支持 Markdown