#API 速查手册 (Cheatsheet)
本文整理了开发 SFMC 业务模块时常用的 SAPI 核心接口与代码片段。
#1. 模块入口与注册 (ModuleRegistry)
每个模块在 sapi/src/index.ts 中通过 ModuleRegistry.register 注册:
import { ModuleRegistry } from "@sfmc-bds/sdk/module-loader";
import { Command, Msg, Permission } from "@sfmc-bds/sdk/sapi/runtime";
// 注册玩家命令 /c:tp;需在模块顶层注册以参与启动期命令收集
Command.register(
"tp",
"tp.use",
(player) => {
if (player) Msg.info("正在传送至主城...", player);
},
"传送至主城",
"feature-teleport"
);
// 需要名称或数量时声明 parameters。可选参数必须放在最后,回调按声明顺序接收。
Command.register(
"pay",
"pay.use",
(player, target, amount) => {
if (player) Msg.info(`准备向 ${String(target)} 支付 ${String(amount)}`, player);
},
"向玩家付款",
"feature-pay",
undefined,
{
parameters: [
{ name: "target", type: "string" },
{ name: "amount", type: "integer" },
],
}
);
ModuleRegistry.register({
id: "feature-teleport",
afterWorldLoad: false, // 是否需要等待世界完全加载后再执行 init
lifecycle: {
// 1. 注册权限节点
registerPermissions() {
Permission.register("tp.use", 0); // Any=0, Member=1, OP=2, Admin=3
Permission.register("tp.admin", 2);
},
// 2. 注册 Minecraft 原生或自定义事件
registerEvents() {
// 在此处订阅 world.afterEvents
},
// 3. 异步初始化(读写配置、建表等)
async init() {
console.log("[feature-teleport] 初始化完成");
},
// 4. 卸载与资源释放
cleanup() {
// 清理定时器与缓存
},
},
});#2. 消息输出 (Msg)
业务代码中请避免直接调用 player.sendMessage(),统一使用 SDK 提供的 Msg 助手以保持前缀与色彩风格统一:
import { Msg } from "@sfmc-bds/sdk/sapi/runtime";
import { world } from "@minecraft/server";
// 发送给指定玩家(参数顺序:消息文本在前,玩家对象在后)
Msg.info("这是一条常规提示", player);
Msg.success("操作成功完成", player);
Msg.warning("注意:此区域禁止 PvP", player);
Msg.error("余额不足,操作失败", player);
Msg.tips("输入 /c:menu 可打开快捷菜单", player);
// 全服广播原生消息
world.sendMessage("§f[*] 全服公告:服务器将在 10 分钟后例行维护");#3. 表单排版 (ListFormInfo)
使用 ActionFormData 构建菜单面板时,可通过 ListFormInfo 格式化正文行:
import { ActionFormData } from "@minecraft/server-ui";
import { ListFormInfo } from "@sfmc-bds/sdk/sapi/runtime";
const form = new ActionFormData()
.title("领地管理面板")
.body(ListFormInfo([
"当前领地:[主城保护区]",
"领地主人:ServerAdmin",
"当前权限:允许移动 / 禁止破坏",
]))
.button("购买领地")
.button("权限设置")
.button("§c返回上一页"); // 仅返回/关闭按钮建议带红字
form.show(player).then((response) => {
if (response.canceled) return;
// 处理点击选项
});#4. 数据库读写与事务 (@sfmc-bds/sdk/sapi/db)
使用 @sfmc-bds/sdk/sapi/db 进行 SQLite 数据操作:
基础查询与写入
事务操作 (Transaction)
import { db, sql } from "@sfmc-bds/sdk/sapi/db";
// 1. 初始化建表
await db.execute(sql`
CREATE TABLE IF NOT EXISTS player_stats (
player_id TEXT PRIMARY KEY,
points INTEGER NOT NULL DEFAULT 0,
last_login INTEGER NOT NULL
)
`);
// 2. 插入或更新记录
await db.execute(sql`
INSERT INTO player_stats (player_id, points, last_login)
VALUES (${player.id}, 100, ${Date.now()})
ON CONFLICT(player_id) DO UPDATE SET
points = points + 100,
last_login = excluded.last_login
`);
// 3. 查询单条数据
const result = await db.queryOne<{ points: number }>(sql`
SELECT points FROM player_stats WHERE player_id = ${player.id}
`);
console.log(`玩家当前点数: ${result?.points ?? 0}`);import { db, sql } from "@sfmc-bds/sdk/sapi/db";
// 在事务中执行原子扣款与加款
await db.transaction(async (tx) => {
// 1. 扣除发起者点数
const sender = await tx.queryOne<{ points: number }>(sql`
SELECT points FROM player_stats WHERE player_id = ${senderId}
`);
if (!sender || sender.points < amount) {
throw new Error("余额不足");
}
await tx.execute(sql`
UPDATE player_stats SET points = points - ${amount} WHERE player_id = ${senderId}
`);
// 2. 增加接收者点数
await tx.execute(sql`
UPDATE player_stats SET points = points + ${amount} WHERE player_id = ${targetId}
`);
// 3. 写入交易日志
await tx.execute(sql`
INSERT INTO transfer_logs (sender, target, amount, created_at)
VALUES (${senderId}, ${targetId}, ${amount}, ${Date.now()})
`);
});#5. 模块配置读写 (@sfmc-bds/sdk/sapi/config)
每个模块在 <SFMC_ROOT>/configs/<configKey>.json 拥有独立配置文件。模块可在 configs-default/<configKey>.json 声明默认值,平台在安装与更新时会自动补齐缺失项且不覆盖已有值:
import { config } from "@sfmc-bds/sdk/sapi/config";
// 读取配置(第二个参数为默认回退值)
const spawnPoint = await config.get("spawn_point", { x: 0, y: 64, z: 0 });
const enableWelcome = await config.get("enable_welcome", true);
// 运行时修改配置并保存
await config.set("spawn_point", { x: 100, y: 70, z: 200 });#6. 跨模块服务调用 (@sfmc-bds/sdk/sapi/service)
调用其他模块在 manifest.json 中声明的 RPC 服务:
import { service } from "@sfmc-bds/sdk/sapi/service";
// 调用 feature-economy 提供的 balance 查询服务
const res = await service.call<{ balance: number }>("economy.balance", {
playerId: player.id,
});
console.log(`用户余额: ${res.balance}`);