Python 脚本开发
Python 脚本是《我的世界》中国版 Mod SDK 的核心编程方式。通过编写 Python 脚本,你可以监听游戏事件、操作游戏数据、实现 JSON 配置无法完成的复杂玩法逻辑。
本页定位
这是 Python 脚本开发的概览与索引页。我们提供了从零开始的 9 节系列教程,建议按顺序学习。本页帮助你快速了解全貌,再深入各章节。
什么是 Python 脚本
《我的世界》中国版(网易版)的脚本系统采用 Python 2,而非国际版基岩版使用的 JavaScript/TypeScript Script API。两者是完全不同的技术体系,不可混用。
原生 Add-On(JSON 附加包)可以自定义物品、方块、生物等游戏内容的数据配置,但无法实现动态逻辑。例如:
- 玩家右键方块时给予特定物品
- 击杀生物后触发连锁爆炸
- 根据条件动态修改玩家属性
- 制作自定义 UI 界面并与游戏逻辑交互
这些需求都需要 Python 脚本来实现。脚本开发的本质就是一个监听事件 + 调用组件的过程——引擎通过事件告诉你"发生了什么",你通过组件去"做点什么"。
Python 版本
Mod SDK 使用的是 Python 2.7,不是 Python 3。请注意 print 语句(非函数)、字符串编码(unicode / str)、整数除法等差异。部分 Python 3 语法在此环境下无法运行。
开发环境
安装 Python 2
前往 Python 官网下载页,在 "Looking for a specific release" 部分找到最新的 Python 2.x 版本下载安装。
安装时务必勾选 "Add python to PATH"(将 Python 添加到环境变量),其余保持默认即可。
安装 IDE
推荐使用 VS Code 作为开发 IDE,并安装 MC Dev Tools 插件以获得更好的开发体验(语法高亮、模板生成等)。PyCharm Community 也是不错的选择。
安装 Mod SDK 补全库
补全库为你的 IDE 提供 Mod API 的代码提示和自动补全功能。
方式一:通过 MC Studio 安装
打开 MC Studio 编辑器 → 工具菜单,选择对应版本的补全库下载即可。
方式二:通过 pip 手动安装
# 安装最新版补全库
python -m pip install mc-netease-sdk
# 升级到最新版本
python -m pip install --upgrade mc-netease-sdk
# 指定 Python 路径安装(系统存在多个 Python 时)
C:\path\to\python.exe -m pip install mc-netease-sdk
# 安装特定版本(在 pypi.org/project/mc-netease-sdk 查询可用版本)
python -m pip install mc-netease-sdk==版本号脚本目录结构
脚本文件位于行为包内,以一个专属文件夹组织。以 tutorialScripts 为例:
behavior_pack_xxx/
├── entities/
├── tutorialScripts/ # 脚本根目录
│ ├── __init__.py # Python 模块标识(内容可为空,文件必须存在)
│ ├── modMain.py # Mod 入口文件(必须直接在脚本根目录下)
│ ├── tutorialClientSystem.py # 客户端逻辑
│ └── tutorialServerSystem.py # 服务端逻辑
├── manifest.json
└── ...| 文件 / 文件夹 | 说明 |
|---|---|
xxxScripts/ | 脚本根目录,会被添加到 Python 运行环境,可通过此路径 import |
__init__.py | Python 模块标识文件,内容可为空但必须存在 |
modMain.py | 必需。Mod 入口文件,用于注册初始化和销毁函数。必须放在脚本根目录下,否则打包后在手机端会失效 |
xxxClientSystem.py | 客户端 System,处理渲染、UI、特效等表现层逻辑 |
xxxServerSystem.py | 服务端 System,处理游戏规则、数据操作等核心逻辑 |
命名规范
为避免与其他 Mod 的脚本冲突,脚本目录应具有足够的区分度。推荐采用:
[团队名称][Mod名称]Scripts例如 SDKTeamTestScripts、MyTeamRPGScripts。更改文件夹名称后,代码中所有相关的 import 路径也需要同步修改。
modMain.py 入口
modMain.py 是整个 Mod 的 Python 入口。引擎通过装饰器识别初始化和销毁函数,在游戏生命周期的对应阶段自动调用。
# -*- coding: utf-8 -*-
from mod.common.mod import Mod
@Mod.Binding(name="MyMod", version="0.0.1")
class MyMod(object):
def __init__(self):
pass
@Mod.InitServer()
def MyModServerInit(self):
# 服务端初始化:注册 ServerSystem、初始化数据等
pass
@Mod.DestroyServer()
def MyModServerDestroy(self):
# 服务端销毁:保存数据、清理资源
pass
@Mod.InitClient()
def MyModClientInit(self):
# 客户端初始化:注册 ClientSystem、初始化 UI 等
pass
@Mod.DestroyClient()
def MyModClientDestroy(self):
# 客户端销毁:清理 UI、恢复设置
pass| 装饰器 | 作用 |
|---|---|
@Mod.Binding(name, version) | 将类绑定为 Mod 入口,name 为 Mod 名称,version 为版本号 |
@Mod.InitServer() | 标记服务端初始化函数,游戏服务端启动时调用 |
@Mod.InitClient() | 标记客户端初始化函数,游戏客户端启动时调用 |
@Mod.DestroyServer() | 标记服务端销毁函数,服务端关闭时调用 |
@Mod.DestroyClient() | 标记客户端销毁函数,客户端关闭时调用 |
通常在 InitServer / InitClient 中注册对应的 System 类:
@Mod.InitServer()
def MyModServerInit(self):
import mod.server.extraServerApi as serverApi
serverApi.RegisterSystem(
"MyMod", # Mod 命名空间
"MyModServerSystem", # System 名称
"myModScripts.server.myServerSystem.MyServerSystem" # System 类路径
)Client-Server 分离
Mod SDK 严格区分服务端和客户端,这是脚本架构中最重要的概念之一。
| 服务端 (Server) | 客户端 (Client) | |
|---|---|---|
| 职责 | 游戏逻辑、数据操作、规则判定 | 渲染、UI、特效、音效 |
| 基类 | ServerSystem | ClientSystem |
| API 模块 | mod.server.extraServerApi | mod.client.extraClientApi |
| 事件 | 服务端事件 | 客户端事件 |
| 组件 | 服务端组件 | 客户端组件 |
关键规则:
- 服务端和客户端的代码必须互相独立,不可互相 import
- 使用对方的事件或组件不会生效
- 游戏逻辑(如给予物品、判定伤害)写在服务端
- 表现逻辑(如 UI 显示、粒子特效)写在客户端
- 跨端数据传递通过自定义事件实现
安全原则
服务端是权威的。所有涉及游戏规则和数据的判定必须在服务端完成。客户端发送的自定义事件中,引擎会自动注入 __id__ 字段标识发送者玩家,该值由引擎注入,无法伪造。服务端应使用 __id__ 来确认玩家身份,而非依赖客户端自行传递的 playerId。
核心开发模式
Python 脚本开发的核心模式可以用一句话概括:
监听事件 → 在回调函数中 → 调用组件读写游戏数据
# 1. 监听事件:当玩家右键方块时触发
self.ListenForEvent(
serverApi.GetEngineNamespace(),
serverApi.GetEngineSystemName(),
"ServerBlockUseEvent",
self, self.OnBlockUse
)
# 2. 在回调中调用组件:给玩家一把钻石剑
def OnBlockUse(self, args):
playerId = args["playerId"]
blockName = args["blockName"]
if blockName == "mymod:special_block":
comp = serverApi.GetEngineCompFactory().CreateItem(playerId)
comp.SpawnItemToPlayerInv(
{"itemName": "minecraft:diamond_sword", "count": 1, "auxValue": 0},
playerId
)几乎所有的 Mod 功能都遵循这个模式。掌握了事件和组件,就掌握了脚本开发的核心。
事件系统概述
事件是引擎与脚本之间的通信桥梁。引擎在特定时机(如玩家攻击、方块被破坏)广播事件,脚本注册回调函数来响应。
核心 API
| 方法 | 说明 |
|---|---|
ListenForEvent(namespace, systemName, eventName, instance, func) | 注册事件监听 |
UnListenForEvent(namespace, systemName, eventName, instance, func) | 取消事件监听 |
BroadcastEvent(eventName, eventData) | 广播自定义事件 |
NotifyToServer(eventName, eventData) | 客户端向服务端发送事件 |
NotifyToClient(playerId, eventName, eventData) | 服务端向指定客户端发送事件 |
自定义事件
除了引擎内置事件,你可以定义自己的事件用于 Client-Server 通信:
# 客户端 → 服务端
self.NotifyToServer("MyRequestEvent", {"action": "buy", "itemId": "sword_01"})
# 服务端接收(引擎自动注入 __id__ 标识发送者)
def OnMyRequestEvent(self, args):
playerId = args["__id__"] # 安全的玩家标识,不可伪造
action = args["action"]详细内容请参阅 S3. 事件系统 和 S5. 自定义事件与通信。
组件系统概述
组件是读写游戏数据的接口。通过 GetEngineCompFactory() 工厂方法创建对应类型的组件实例,然后调用其方法来获取或设置数据。
import mod.server.extraServerApi as serverApi
# 创建物品组件
itemComp = serverApi.GetEngineCompFactory().CreateItem(playerId)
# 获取玩家背包所有物品
allItems = itemComp.GetPlayerAllItems(
serverApi.GetMinecraftEnum().ItemPosType.INVENTORY
)
# 创建生命值组件
healthComp = serverApi.GetEngineCompFactory().CreateAttr(entityId)
# 设置生命值
healthComp.SetAttrValue(serverApi.QueryMinecraftAttrType().HEALTH, 20.0)
# 创建位置组件
posComp = serverApi.GetEngineCompFactory().CreatePos(entityId)
# 获取实体坐标
pos = posComp.GetPos()组件同样区分服务端和客户端。服务端组件可读写游戏核心数据,客户端组件主要用于表现层。
ModAttr 自动同步
当你需要在 Client 和 Server 之间同步自定义数据时,可以使用 CreateModAttr 组件。通过它注册的属性会在两端自动同步,无需手动发送自定义事件,适合血量条、分数等需要实时同步的场景。
详细内容请参阅 S4. 组件调用。
调试方法
日志输出
Mod 开发中主要通过打印日志来调试。日志会显示在 MC Studio 的**"脚本测试日志"**窗口中。
# 方式一:print(简单直接)
print "===MyMod=== OnBlockUse:", args
# 方式二:mod_log 模块(推荐,支持格式化)
from mod_log import logger
logger.info("===MyMod=== player %s used block %s", playerId, blockName)建议日志加上 Mod 名称前缀(如 ===MyMod===),方便在大量日志中快速定位。
热更新
MC Studio 支持开发时热更新。修改本地 Python 文件后切回 Studio 界面,会自动重载修改的模块,无需重启游戏。
热更新对函数内部实现支持较好,但涉及全局变量、新增类/文件等可能不会生效。此时需要退出到菜单界面,重新进入存档加载完整的 Mod。
调试建议
- 在关键逻辑分支处添加日志,确认代码执行路径
- 注意某些事件每 tick 都会触发(如
ServerBlockUseEvent按住右键时),需加防抖逻辑 - 检查服务端/客户端是否混用了对方的 API
- 编码问题出错时,检查中文字符串是否加了
u前缀
教程系列导航
以下 9 节教程从零开始,循序渐进地覆盖 Python 脚本开发的各个方面:
| 章节 | 主题 | 核心内容 |
|---|---|---|
| S1. 环境准备与第一个脚本 | 开发环境搭建 | Python 2 安装、IDE 配置、mod.json 结构、Hello World 脚本 |
| S2. Client-Server 架构 | 双端架构 | 服务端与客户端的职责划分、System 基类、ModAttr 自动同步 |
| S3. 事件系统 | 核心机制 | ListenForEvent 注册回调、事件参数、可取消事件 |
| S4. 组件调用 | 读写游戏数据 | GetEngineCompFactory 工厂模式、Item / Attr / Game 组件 |
| S5. 自定义事件与通信 | 跨端通信 | NotifyToServer / NotifyToClient、__id__ 安全标识 |
| S6. 制作 UI 界面 | 界面布局 | JSON 画布定义、控件类型、UI 编辑器操作 |
| S7. UI 脚本交互 | 界面逻辑 | ScreenNode 生命周期、CreateUI 与 PushScreen 的区别 |
| S8. 实战:计分板系统 | 综合实战 | 事件 + 组件 + 跨端通信 + UI 的完整开发链路 |
| S9. 调试与热更新 | 开发效率 | 日志调试技巧、热更新机制、常见错误排查 |
学习建议
建议先通读本页建立整体认知,然后从 S1 开始逐步实践。每节教程都包含可运行的代码示例,动手操作是最好的学习方式。
