iNeed创作者文档

引擎接入

本页目录

Godot 接口手册

适用插件 0.1.1、协议 v1(既有 request 方法仍兼容 0.1.0);本文对照平台运行时 1.0.1。最新方法是否可用以当前会话协商为准。SDK 与源码 · 冻结协议基线。本页为开发参考,不修改旧协议。

调用约定

先 await INeed.initialize(),检查 result.ok,再 INeed.supports("完整方法名")。所有异步方法返回 Dictionary;数据仅允许 JSON 类型,不传 Node、Resource、Callable、Vector2 或二进制对象。向量应由游戏明确转换为普通字段。

var result: Dictionary = await INeed.request("payments.inventory", {"productKey": "entry_ticket"})
if result.get("ok", false):
    var remaining := int(result.get("value", 0))
    print("当前会话剩余次数:", remaining)
else:
    var error: Dictionary = result.get("error", {})
    print(error.get("code", "REQUEST_FAILED"), ": ", error.get("message", ""))

成功外层是 {ok:true,value:...};失败外层是 {ok:false,error:{code,message}}。某些底层业务返回自身的 ok 字段,仍放在 value 内。不得假定所有 value 都是数组或都有 data 字段。

插件简写

GDScript 对应桥接方法 说明
initialize() hello 协商协议;返回 protocol/runtimeVersion/capabilities
supports(method) 本地能力查询 仅初始化成功后有效,返回 bool
request(method, params = {}) 指定方法 通用异步调用
login() login 平台认证;返回会话数据
buy(product_key) payments.buy 单个商品的可信确认与购买
open_store() ui.store 平台商品列表,选购后返回购买结果
open_leaderboard(board_key, scope = "world") ui.leaderboard 平台排行榜窗口
show_rewarded(placement, action_id) ads.rewarded 真实广告与可信结算

插件 0.1.1 新增以下包装器;旧 0.1.0 使用 request 接口。没有 INeed.get_account() 简写。

GDScript 行为
ensure_logged_in() 返回当前账号;游客先登录,失败就停止
consume(product_key, quantity, request_id) 确保登录,只消费,不购买
buy_and_consume(product_key, quantity, request_id) 确保登录,先消费已有库存,不足时购买一次再消费

buy 会先确保登录;账号取消或失败时不购买。组合的完整结果、部分成功和幂等恢复见商品购买与消耗。组合失败可能附加 context.purchase/stage/requestId,原 error 不被隐藏;它不是原子交易。stage=purchase_unknown 表示购买结果待核实,after_purchase 表示已取得购买成功回执。新包装器可返回 PURCHASE_UNCONFIRMED,阻止未知购买结果下再买;这不是新增的远程协议错误。

账号及购买数据

下表“返回”均指外层成功结果的 value。读取账号、商品、库存、权益的是当前 SDK 会话快照,不能作为服务端授权依据。

方法 params 返回与读取位置
account.get 空 账号对象或 null;id、nickname、avatarUrl、username、balanceCoins 等;字段为空须处理
login 空 会话对象,内含 account;推荐登录结束后重新 account.get
payments.products 空 商品数组;productKey、name、description、priceCoins、type、grantQuantity;type 为 permanent/consumable;不要销售 systemManaged 项
payments.inventory 空 [{productKey,quantity}];无库存可能为空数组
payments.inventory productKey: String 此商品数量 Number,没找到返回 0
payments.entitlements 空 {buyout,products:[{productKey,acquiredAt}]};不包含消耗品库存
payments.buy productKey: String 购买结果,可能含 orderId、noCharge、fulfillment、session;最终 UI 从更新后的会话权益/库存读取
payments.consume productKey、quantity、requestId consumptionId、noChange、productKey、quantity、remainingQuantity、session;noChange=true 表示相同操作重放
ui.store 空 选商品并购买;返回与 buy 相同业务结果;关闭可能为 CANCELLED

consume 的 quantity 为正整数,服务端上限 1,000,000;requestId 为 16–80 位英文字母、数字、下划线或连字符。一个真实动作一个 ID,同动作重试完全相同,新动作用新 ID。buy 当前公开参数只有 productKey;不要传入自造 requestId 并声称购买已经跨刷新幂等。

排行榜数据与提交

方法 params 返回与读取位置
leaderboards.list 空 {ok,boards,profile};boards 为榜单配置数组
leaderboards.get boardKey;scope 默认 world;page 默认 1;可选 pageSize {ok,board,scope,region,entries,personalBest,personalRank,total,page,pageSize}
leaderboards.submit boardKey、runId、score、durationMs;可选 endedAt、stats {ok,receipt};receipt 含 runId、boardKey、score、previousBest、personalBest、isPersonalBest、deltaToBest、rank、submittedAt、replayed
leaderboards.profile 空 {ok,profile},profile 为昵称、头像、地区及修改地区时间信息
leaderboards.region countryCode、provinceCode;可选 cityCode {ok,profile};提交平台认可的地区代码,不能把中文地区名当代码
ui.leaderboard boardKey;scope 默认 world 点击返回通常 {closed:true};其他关闭路径可能 CANCELLED

scope 为 world/province/city。boards 项含 boardKey/title/sortOrder/minScore/maxScore/minDurationMs/maxDurationMs;entries 项含 rank/userId/nickname/avatarUrl/score/achievedAt/isMe。按返回的 pageSize 和 total 分页,不依赖私有上限。地区未知时提示选择或返回世界榜;不要自行定位用户精确位置。

runId 在真实开局时生成,结束后冻结 score、durationMs 及可选 ISO 8601 endedAt。stats 为数值或布尔值的对象;不要放玩家秘密或聊天全文。示例:

var frozen_run: Dictionary = {
    "boardKey": "survival_score",
    "runId": "run_" + Crypto.new().generate_random_bytes(16).hex_encode(),
    "score": 1200,
    "durationMs": 85000
}
# 上述数值只演示形状,正式游戏须用真实开局与结算值。
var result: Dictionary = await INeed.request("leaderboards.submit", frozen_run)
if result.get("ok", false):
    var receipt: Dictionary = result.get("value", {}).get("receipt", {})
    print(receipt.get("personalBest"))
# 网络重试复用 frozen_run;示例成绩禁止提交正式榜单。

激励广告

ads.rewarded params 为 {placement,actionId}。placement 为 1–64 位英文字母、数字、下划线或连字符;actionId 为 16–80 位同类字符。

成功 value 是 {receiptId,actionId,placement,reward,replayed}。reward 是平台为该广告位配置并在创建动作时固定的 JSON 对象,没有通用的 coins 或 quantity 必填字段;与平台约定后才能解释。replayed=true 仍是同一凭据,不能重复应用奖励。取消、无填充、超时均不得当成功。详见广告 Skill。

存档

方法 params 返回
storage.load 空 {value,version,schemaVersion,scope};首次 value=null、version=0
storage.save value: JSON;baseVersion: 非负整数;schemaVersion 默认 1 至少 {version,scope};不要依赖保存响应一定回传 value

scope 为 guest/preview/account。schemaVersion 由游戏维护,平台不会自动转换玩法数据。当前运行时要求 schemaVersion 正整数且不超过 1,000,000。先 load 取得 version,再作为 baseVersion 保存;成功后更新本地版本。1 MiB 包含平台存储编码开销和既有数据,游戏内容应留余量,最终以服务器校验为准。

事件

INeed.platform_event.connect(handler),handler 签名为 (name: String, data: Dictionary)。

name data 游戏责任
pause reason 为触发弹窗的方法 保存先前暂停/音频状态,暂停游戏
resume reason 恢复先前状态;不是交易成功通知
account.changed account 对象或 null 使旧账号异步结果失效,清理显示缓存,重读新身份数据

当前没有 purchase.completed、inventory.changed 等通用 Godot 事件;以调用结果和会话读取驱动 UI。同一时间只允许一个平台模态调用,重复可能 BUSY。游戏生命周期处理代码见界面建议。

错误处理与数据来源

常见代码及重试策略见异常与恢复。桥接不会返回任意 HTTP 响应头,所以不要假设每个结果都有 traceId。排错记录作品、环境、时间、账号标识、方法、业务 ID 和实际返回码;向平台申请查询交易/消费/奖励账本。不要记录 token、密码和完整私密存档。

本文依据公开插件及平台同版本实现整理;不要求创作者调用内部管理 API。API 扩展必须先由平台实现并公告,再按 supports 接入。