关于 minecraft-server-scriptapi
指导 AI Agent 使用 Minecraft Server ScriptAPI 的开发技能,面向编写事件、实体、组件和命令逻辑的开发者。它强调依据 Microsoft Learn 核实 API,并处理执行权限与时序限制。
主要功能
- 01按任务查阅官方 API 文档
- 02事件、维度与组件使用模式
- 03自定义命令和脚本事件指导
- 04执行权限与早期执行检查
- 05类型安全与性能注意事项
适用场景
- 01实现世界事件订阅
- 02编写自定义命令回调
- 03安排跨 tick 的耗时任务
- 04核对 API 的执行限制
MCP 相关
该技能指定 Microsoft Learn MCP 端点,并使用 microsoft_docs_search 搜索文档、使用 microsoft_docs_fetch 获取完整签名和详情。
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ kaaariyaaa/ scriptapiserverskill --skill minecraft-server-scriptapi安装后在 Claude Code 中输入/minecraft-server-scriptapi确认已加载。
附带文件SKILL.ja.md
详细介绍
Minecraft Server ScriptAPI
工作流
- 范围:确定任务内容(事件、实体、组件、命令、时序)。除非请求使用 Beta/预览版,否则默认使用最新稳定版。
- 文档:从模块索引导航至具体的类/接口/事件。以 Microsoft Learn 为准。缺少详细信息时,通过 MCP 搜索。
- 输出:引用准确的 API 名称。提供包含所需导入项的最小可运行示例。创建自定义辅助函数前,先确认不存在官方等效方案。
- 对于
CustomCommandParamType之类的枚举,务必查阅 Microsoft Learn,确认其是否可用。 @minecraft/vanilla-data不在 Microsoft Learn 上,因此跳过对此类枚举的 MCP 搜索。
- 对于
常见模式
事件
- 订阅/取消订阅
world/system事件。添加防护逻辑以提升性能。
维度
- 使用
world.getDimension(MinecraftDimensionTypes.<Dimension>),并根据任务选择合适的维度。
组件
- 访问前先检查组件是否存在。
- 使用类型化 ID:
EntityComponentTypes、BlockComponentTypes、ItemComponentTypes。
调度
- 使用
system.run、system.runTimeout、system.runInterval、system.runJob。
标识符
- 必须使用
@minecraft/vanilla-data枚举:MinecraftBlockTypes、MinecraftEntityTypes、MinecraftItemTypes、MinecraftDimensionTypes、MinecraftEffectTypes、potionEffect、potionDelivery、feature、enchantment、cooldownCategory、cameraPresets、biome。 - 自定义 ID:必须包含命名空间前缀(例如,
example:cmd)。每个附加包使用一个统一的前缀。
示例:
import { world, system } from "@minecraft/server";
import { MinecraftDimensionTypes, MinecraftBlockTypes } from "@minecraft/vanilla-data";
system.runInterval(() => {
const dimensions = [MinecraftDimensionTypes.Overworld, MinecraftDimensionTypes.Nether];
const blocks = [MinecraftBlockTypes.Stone, MinecraftBlockTypes.Sand, MinecraftBlockTypes.GrassBlock];
for (const dimension of dimensions) {
for (const block of blocks) {
world.getDimension(dimension).setBlockType({ x: 0, y: 0, z: 0 }, block);
}
}
});
权限模式
只读
- 在模拟/事件/刻开始之前。不得修改世界。
- 解决方法:延后至
system.run/runTimeout。
文档验证
- 使用任何方法/属性时,务必查阅 Microsoft Learn,确认其是否支持只读安全或早期执行。
- 查找 API 参考中的明确说明(只读/早期执行),并严格遵守。
- 仅对于箭头函数回调,还要检查是否有受限执行说明,例如:
- “此闭包以受限执行权限调用。”
- “此函数不能在受限执行模式下调用。”
- 如果有适用的受限执行说明,请检查箭头函数主体,确保没有违反只读或早期执行要求;必要时使用
system.run延后执行。
示例(延后只读操作):
world.beforeEvents.playerInteractWithBlock.subscribe((event) => {
const player = event.player;
system.run(() => {
player.runCommand("say ok");
});
});
早期执行
- 在世界加载前。许多 API 不可用。
- 解决方法:延后至
world.afterEvents.worldLoad或system.run。 - 在根级别订阅,以免错过事件。
早期执行中安全的操作:
- 事件订阅(
world/system的beforeEvents/afterEvents) system.clearJob、clearRun、run、runInterval、runJob、runTimeout、waitTicksBlockComponentRegistry.registerCustomComponent、ItemComponentRegistry.registerCustomComponent
自定义命令
- 接口:
CustomCommand(name、description、permissionLevel、mandatoryParameters、optionalParameters)。 - 参数:
CustomCommandParameter(name、type、可选的enumName)。 - 参数类型和箭头函数参数类型:
String->StringPlayerSelector->PlayerLocation->Vector3ItemType->ItemTypeInteger->NumberFloat->NumberEnum->StringEntityType->EntityTypeEntitySelector->EntityBoolean->BoolBlockType->BlockType
- 注册枚举:
CustomCommandRegistry.registerEnum(name, values)。 - 注册命令:
CustomCommandRegistry.registerCommand(customCommand, callback)。 - 回调:
(origin, ...args) => CustomCommandResult。 - 自定义命令回调以受限执行权限运行,因此不要直接调用受只读限制的方法;如有需要,使用
system.run延后执行。 - 使用箭头函数时,参数名称和顺序应与
CustomCommandParameter.name列表一致;定义了参数时,避免使用不匹配的名称或通用的args。
示例:
import {
system,
StartupEvent,
CommandPermissionLevel,
CustomCommandParamType,
CustomCommandStatus,
} from "@minecraft/server";
system.beforeEvents.startup.subscribe((init: StartupEvent) => {
init.customCommandRegistry.registerEnum("example:mode", ["on", "off"]);
init.customCommandRegistry.registerCommand(
{
name: "example:demo",
description: "Command demo",
permissionLevel: CommandPermissionLevel.GameDirectors,
cheatsRequired: true,
mandatoryParameters: [
{ type: CustomCommandParamType.String, name: "msg", },
{ type: CustomCommandParamType.Enum, name: "example:mode"},
],
optionalParameters: [
{ type: CustomCommandParamType.Boolean, name: "silent" },
{ type: CustomCommandParamType.Integer, name: "count" },
],
},
(origin, msg, mode, silent, count) => {
const msgValue = String(msg ?? "ok");
const modeValue = String(mode ?? "off");
const silentValue = Boolean(silent ?? false);
const countValue = Number(count ?? 1);
return {
status: CustomCommandStatus.Success,
message: silentValue
? undefined
: `[${origin.sourceType}] ${msgValue} mode=${modeValue} count=${countValue}`,
};
}
);
});
脚本事件
- 发送:
system.sendScriptEvent(id, message)(带命名空间的 ID,载荷字符串)。 - 接收:
system.afterEvents.scriptEventReceive.subscribe(callback, options?)。 - 事件:
ScriptEventCommandMessageAfterEvent(id、message、sourceType、可选的sourceEntity/sourceBlock/initiator)。 - 筛选器:
ScriptEventMessageFilterOptions.namespaces。
示例:
import { system, world, ScriptEventSource } from "@minecraft/server";
system.afterEvents.scriptEventReceive.subscribe((event) => {
const { id, message, sourceType, initiator, sourceEntity, sourceBlock } = event;
if (id !== "example:say") return;
switch (sourceType) {
case ScriptEventSource.Block:
world.sendMessage(`sendBy:${sourceBlock?.typeId ?? "unknown"} ${message}`);
break;
case ScriptEventSource.Entity:
world.sendMessage(`sendBy:${sourceEntity?.typeId ?? "unknown"} ${message}`);
break;
case ScriptEventSource.NPCDialogue:
world.sendMessage(`sendBy:${initiator?.typeId ?? "unknown"} ${message}`);
break;
case ScriptEventSource.Server:
world.sendMessage(`sendBy:server ${message}`);
break;
}
});
性能
- 事件中的高开销工作:使用
system.runJob(generator)将任务分散到多个刻中执行。 - 遍历大型集合前,先进行短路判断。
system.run 变体
run:下一刻执行。runTimeout(cb, ticks):延迟 N 个刻。误用0可能导致紧密循环。runInterval(cb, ticks):每隔 N 个刻重复执行,直到调用clearRun。runJob(generator):执行长时间运行的任务。每次迭代应保持精简。
类型安全
- 使用
typeId检查,并验证组件是否存在。 - 仅对文档中列出的
@minecraft/server类使用instanceof。
最简模板
事件订阅:
world.afterEvents.playerJoin.subscribe((event) => {
const player = event.player;
});
刻循环:
system.runInterval(() => {
// tick logic
}, 1);
获取维度:
const overworld = world.getDimension(MinecraftDimensionTypes.Overworld);
生成实体:
const overworld = world.getDimension(MinecraftDimensionTypes.Overworld);
overworld.spawnEntity(MinecraftEntityTypes.Zombie, { x: 0, y: 80, z: 0 });
给予物品:
const item = new ItemStack(MinecraftItemTypes.Diamond, 1);
player.getComponent("inventory")?.container?.addItem(item);
应用效果:
player.addEffect(MinecraftEffectTypes.Speed, 200, { amplifier: 1 });
获取组件(类型化):
const health = entity.getComponent(EntityComponentTypes.Health);
易错点
- 空组件:访问前先检查是否存在。
- 高开销事件:使用
system.runJob。 - 权限:避免违反只读限制或提前执行限制。
- 原始 ID:使用类型化枚举。
- 命名空间:每个附加包使用一个统一前缀。
MCP 工具
- 端点:https://learn.microsoft.com/api/mcp
- 搜索:
microsoft_docs_search(模块 + 类 + 任务)。 - 获取:
microsoft_docs_fetch(完整签名/详情)。
评论
支持 Markdown