脚本 API
tools:运行时能力 API
完整查询弹窗、存档、AI、地图、弱联网、特效、音频和脚本上下文 API。
脚本 API · 运行时能力
只通过 tools 调用运行时能力
`tools` 是 Worker 脚本连接交互、跳转、存档、AI、地图、弱联网、客户端特效与音频的边界。本页列出当前运行时代理实际公开的全部方法。
# 使用合同
- 让编辑器 AI 先查询真实资源 ID,再生成调用。
- 玩家存档写入只放在控件或事件动作脚本中。
- 每个 Promise 都使用
await+try/catch或.then(...).catch(...)。 - 把取消、限流、页面销毁、离线结算和未登录当作正常分支。
- 面向玩家的固定文案先经过
tools.tr(source, params?)。 - 不猜测方法名,不调用私有 Worker 消息,不在 Worker 脚本里绕过代理联网。
Canvas renderer 会额外获得上下文 API tools.canvas,详见渲染布局与 Canvas。客户端特效/音频源码运行在独立前端环境中,不会获得这里的 Worker tools 对象。
# API 地图
| 能力 | 方法 |
|---|---|
| 上下文 | session、getTempData、setTempData、kwargs、tr、delay、runScript |
| 玩家交互 | showToast、showNotify、showDialog、closeCurrentDialog、choose、chooseObjects、inputText、inputNumber |
| 场景与消息 | gotoScene、postMessage、clearMessage |
| 存档与本地数据 | savePlayerDataToLocal、savePlayerDataToCloud、savePlayerDataToCloudForce、getLocalData、setLocalData |
| 运行期样式与资源音频 | setItemStyle、getItemStyle、setDefaultItemStyle、playAudio、pauseAudio、playBackgroundAudio、pauseBackgroundAudio |
| AI | requestAIText、requestAIPropertyChanges、requestAIObjectChanges、四个智能体控制方法与兼容别名 |
| 地图 | getMapGrid、jumpMapGrid、moveMapDirection、canMoveMapGrid、resetMap |
| 弱联网 | uploadWeakOnline、queryWeakOnline、aggregateWeakOnline |
| 客户端表现 | runClientEffect、disposeClientEffect、clearClientEffects、runClientAudio、disposeClientAudio、clearClientAudio |
# 上下文、翻译与延迟
tools.session 在当前页面运行期的可写 Worker 脚本之间共享,刷新后清空。getTempData(key) 和 setTempData(key, value) 读写同一份会话。它不是存档,也不与前端特效/音频的 session 共享。
tools.session.submitLocked = true;
tools.setTempData("selectedObjectId", tools.kwargs.objID);
tools.delay(() => {
tools.session.submitLocked = false;
}, 5);
delay(callback, ticks) 的单位是游戏帧,会受游戏倍速影响;Worker 脚本使用它代替 setTimeout / setInterval。
固定文案在展示前翻译:
tools.showToast(
tools.tr("你获得了{count}个苹果", { count: 3 }),
"success"
);
动态字符串和 <|...|> 占位符使用 player.getString(nameOrText) 解析。parseText 是内部帮助函数,不是公开 API。
# 当前脚本上下文
tools.kwargs 随挂载点变化,使用前先判断字段是否存在:
| 字段 | 含义 |
|---|---|
itemID |
当前控件 ID |
object / objID |
当前可读写对象代理与稳定对象 ID |
screenIndex / isPC |
运行屏幕与设备布局上下文 |
triggerType |
gain、enter、leave、press、release、move、long 或 drop |
pointer |
相对控件、游戏屏幕和浏览器视口的指针快照 |
payload |
Canvas binding 或其他交互入口传入的可序列化参数 |
effectTargetId |
控件/特效逻辑目标 |
effectScopedTargetId |
当前实际渲染屏幕实例目标 |
source / dropTarget |
js_drop 中的拖拽来源和投放目标 |
args |
runScript 显式传入的参数 |
# 弹窗、选择与输入
const result = await tools.choose(
tools.tr("选择奖励"),
tools.tr("请选择一项"),
{
optionNames: [tools.tr("金币"), tools.tr("体力")],
optionValues: ["gold", "stamina"],
optionDescriptions: [tools.tr("通用货币"), tools.tr("行动能量")],
multiple: false
}
);
if (result?.value === "gold") player.addPro("金币", 10);
| 方法 | 重要配置与返回 |
|---|---|
showToast(msg, type?, duration?, position?, config?) |
即时中间/顶部/底部提示;config 支持颜色、背景和样式 |
showNotify(msg, background?, color?, duration?) |
顶部通知 |
showDialog(title, msg, config?, ok?, cancel?) |
`Promise<data |
closeCurrentDialog() |
关闭控件所属 dialog/subdialog,不能关闭 tools.showDialog 交互 |
choose(title, description, config, ok?, cancel?) |
Promise 结果单选读 value,多选读 values |
chooseObjects(title, description, config, ok?, cancel?) |
候选放在 config.objectList,返回对象 ID 或 ID 数组 |
inputText(title, description?, config?, ok?, cancel?) |
支持 defaultValue、maxLength、multiline、rows、placeholder |
inputNumber(title, description?, config?, ok?, cancel?) |
支持 defaultValue、min、max、step、integer |
关闭或取消交互可能返回 undefined,基础设施错误仍会 reject。交互完成后必须重新校验条件,再提交状态。
# 场景与本地消息
tools.gotoScene("主城", 0); // 当前屏
tools.gotoScene("背包", 2); // 中屏;1/2/3 = 左/中/右
tools.postMessage(tools.tr("已获得新线索"), "private");
tools.clearMessage("all");
postMessage 只插入本地私有消息或服务器样式消息,不是玩家之间的全局聊天。跨玩家通信使用平台聊天插件。
# 存档与本机数据
tools.savePlayerDataToLocal();
tools.savePlayerDataToCloud();
tools.savePlayerDataToCloudForce();
await tools.setLocalData("tutorial_seen", "1");
const seen = await tools.getLocalData("tutorial_seen");
本机键值数据不是玩家存档。云存档要求运行环境支持且玩家已登录。savePlayerDataToCloud() 打开云存档流程;savePlayerDataToCloudForce() 直接请求一次云保存。任何存档 API 都不会开放其他玩家的完整存档。
# 运行期样式与资源音频
tools.setItemStyle("购买控件", "buttonstyle", "background:#0ea5e9", tools.kwargs.objID);
const override = tools.getItemStyle("购买控件", "buttonstyle", tools.kwargs.objID);
tools.setDefaultItemStyle("购买控件", "buttonstyle", tools.kwargs.objID);
tools.playAudio("/audio/click.mp3");
tools.playAudio("/audio/loop.mp3", true);
tools.pauseAudio("/audio/loop.mp3");
tools.playBackgroundAudio("/audio/bgm.mp3");
tools.pauseBackgroundAudio();
样式方法只修改当前运行期覆盖,不会写回项目。资源音频方法播放已有 URL;需要合成器、音序和可追踪的长音频时使用客户端音频脚本。
# 嵌套脚本
runScript(scriptText, args?) 执行同一 Worker 环境中的 JavaScript 源码,不会按名称查找脚本资源。
const source = `
const amount = Number(tools.kwargs.args?.amount || 0);
player.addPro("金币", amount);
return player.getPro("金币");
`;
const total = tools.runScript(source, { amount: 10 });
嵌套脚本继承安全的当前上下文、保留当前对象 ID,并从 tools.kwargs.args 读取显式输入;离线结算会跳过。不能把玩家输入、联网结果或 AI 输出当成源码,也不能创建无界递归链。
# AI 请求与智能体控制
const text = await tools.requestAIText("总结玩家刚才的行动");
await tools.requestAIPropertyChanges("按已验证规则发放任务奖励");
await tools.requestAIObjectChanges("按结构创建一名旅行商人");
await tools.sendAIAgentInput("向导智能体", "继续");
await tools.chooseAIAgentOption("向导智能体", 0);
tools.undoAIAgentTurn("向导智能体");
tools.resetAIAgentSession("向导智能体");
三种 request 方法的可选 outbindproperty 可指向 table_<表格ID>_<行>_<列> 或可写 namesetting_<id>。AI 调用会排队,受额度和输入长度限制,在部分环境不可用,并在离线结算中跳过。
旧项目兼容别名仍公开:
| 推荐名称 | 兼容别名 |
|---|---|
requestAIText |
sendAIMessage |
requestAIPropertyChanges |
sendAIProMessage |
requestAIObjectChanges |
sendAIGetObjMessage |
sendAIAgentInput |
sendAIGameMessage |
chooseAIAgentOption |
triggerAIGameChoice |
undoAIAgentTurn |
regretAIGame |
resetAIAgentSession |
resetAIGame |
# 地图与弱联网
| 方法 | 行为 |
|---|---|
getMapGrid(mapIDOrName) |
读取当前格子快照 |
jumpMapGrid(mapIDOrName, gridIDOrName) |
检查存在后传送,跳过邻接/需求 |
moveMapDirection(mapIDOrName, direction) |
执行方向、邻接和需求规则 |
canMoveMapGrid(mapIDOrName, gridIDOrName) |
只检查可达性,不移动 |
resetMap(mapIDOrName) |
回到地图起始格 |
弱联网只公开插件配置的快照:
| 方法 | 限制与返回 |
|---|---|
uploadWeakOnline() |
Promise<boolean>;每个玩家/项目 3 分钟一次 |
queryWeakOnline(filters, page?, limit?, sort?, groupBy?) |
Promise<QueryResult>;3 秒一次;最多 10 条或 10 组 |
aggregateWeakOnline(filters?) |
Promise<AggregateResult>;3 秒一次;结果缓存约 15 分钟 |
条件树、操作符、分组、返回结构和隐私规则详见弱联网脚本。
# 客户端特效与音频
await tools.runClientEffect(effectSource, {
payload: { text: "-10" },
target: tools.kwargs.effectScopedTargetId,
label: "damage",
mode: "replace"
});
await tools.disposeClientEffect("damage");
await tools.clearClientEffects();
await tools.runClientAudio(audioSource, { label: "battle-loop" });
await tools.disposeClientAudio("battle-loop");
await tools.clearClientAudio();
runClientEffect(source, options?) 支持 payload、target、targets、pointer、waitMs、timeoutMs、label 和 mode;mode: "update" 必须有稳定 label。runClientAudio(source, options?) 支持 payload、pointer、timeoutMs 和 label。六个方法全部返回 Promise,并在离线结算中跳过。
内层源码在独立前端环境中按原生 JavaScript 执行,不会获得 Worker 的 player、objects 或 tools。通过 payload 传入可序列化数据,并使用客户端视觉特效和客户端音频记录的宿主 API。
# 完整运行时索引
| 方法 | 返回/边界 |
|---|---|
tr、delay、getTempData、setTempData、session、kwargs |
同步运行时帮助能力 |
showToast、showNotify、closeCurrentDialog、postMessage、clearMessage、gotoScene |
即时客户端消息/跳转 |
showDialog、choose、chooseObjects、inputText、inputNumber |
玩家交互 Promise |
savePlayerDataToLocal、savePlayerDataToCloud、savePlayerDataToCloudForce |
存档副作用,受登录/环境限制 |
getLocalData、setLocalData |
本机数据 Promise |
setItemStyle、getItemStyle、setDefaultItemStyle |
仅运行期样式覆盖 |
playAudio、pauseAudio、playBackgroundAudio、pauseBackgroundAudio |
资源音频控制 |
runScript |
嵌套源码返回值或 Promise |
requestAIText、requestAIPropertyChanges、requestAIObjectChanges 及别名 |
AI Promise |
sendAIAgentInput、chooseAIAgentOption 及别名 |
智能体 Promise |
undoAIAgentTurn、resetAIAgentSession 及别名 |
智能体动作结果 |
getMapGrid、jumpMapGrid、moveMapDirection、canMoveMapGrid、resetMap |
地图状态/动作 |
uploadWeakOnline、queryWeakOnline、aggregateWeakOnline |
受限流的弱联网 Promise |
runClientEffect、disposeClientEffect、clearClientEffects |
客户端特效 Promise |
runClientAudio、disposeClientAudio、clearClientAudio |
客户端音频 Promise |
# 验收清单
- 每个调用名都能在本页索引或 Canvas 上下文参考中找到。
- 资源 ID 来自查询,而不是按显示名称猜测。
- 每个 Promise 都处理失败、取消、超时、重复输入和页面销毁。
- 离线结算不依赖交互、AI、弱联网、本机数据、特效或音频 Promise。
runScript和 Canvas 模块只加载作者控制的源码。- 特效和音频使用稳定 label,并在所有退出路径清理。
继续阅读:脚本挂载点、弱联网和渲染布局与 Canvas。