🚀 快速入门我的世界 Mod 开发 ​⚠️ 接下来需要 Python2 基础知识

如果你不熟悉 Python 的这些概念(变量、函数、类等),或是还没有安装 Python2 环境,可以先学习 Python 官方教程

1. 创建你的 Addons ​什么是 Addons?Addons 是基岩版的玩法与内容扩展的载体,分为行为包(Behavior Pack)和资源包(Resource Pack)两部分。

在中国版的行为包中,我们可以使用 Python2 编写 Mod 脚本,实现自定义的复杂游戏逻辑。

我们一般推荐使用 MCStudio 来创建你的 Addons(Mod)

左侧切换到 作品库 > 基岩版组件 标签页顶部切换到 附加包 标签页点击右上角 新建 按钮,选择 空白附加包 或 入门预设脚本模板输入 作品名称、命名空间 等信息,点击 启动编辑 启动 MCStudio 编辑器(但是暂时没什么用),也可以点击 仅新建 来创建。2. 创建基础 Mod 框架 ​Addons(Mod)创建完毕后,你可以在 MC Studio 中,找到你刚刚创建的 Addons,点击 更多 > 打开目录,即可在资源管理器中找到和打开 Addons 文件夹。

接着,你可以使用任何代码编辑器打开这个 Addons 文件夹。

可以使用 VS Code,也可以使用 PyCharm 等用于 Python 的 IDE(集成开发环境 的缩写)。

Addons目录结构Addons # Addons 根目录

├── resource_pack/ # 基岩版材质包(MCStudio创建时,会自动生成后缀,这是没问题的)

│ ├── manifest.json # 材质包描述文件

│ └── textures/ # 材质文件目录(目前用不到)

│ ├── blocks/

│ └── items/

├── behavior_pack/ # 基岩版行为包(MCStudio创建时,会自动生成后缀,这是没问题的)

│ ├── manifest.json # 行为包描述文件

│ ├── myScript/ # Mod脚本目录(这个目录名字随便起!)

│ │ ├── modMain.py

│ │ ├── MyServerSystem.py # ServerSystem,你也可以随意放在任何子目录,但是需要在modMain.py中正确注册

│ │ └── MyClientSystem.py # ClientSystem,你也可以随意放在任何子目录,但是需要在modMain.py中正确注册Mod(Python)逻辑位于 行为包 (Behavior Pack,简称BP) 中的 脚本目录,这里我们取名为 myScript,当然你想你可以随便取名。

BP/myScript/modMain.pypythonfrom mod.common.mod import Mod

import mod.server.extraServerApi as serverApi

import mod.client.extraClientApi as clientApi

# 通过Mod.Binding注明这个class是Mod的主入口。

@Mod.Binding(name="MyFirstMod", version="1.0") # Mod名称(name)可以随便取,但是需要唯一且用于下方注册系统和后续注册事件监听。

class MyFirstMod: # 这个类名可以随便取

@Mod.InitServer()

def serverInit(self): # 这个方法名可以随便取,因为已经通过@Mod.InitServer()注明是服务端的初始化方法

serverApi.RegisterSystem("MyFirstMod", "MyServerSystem", "myScript.MyServerSystem.MyServerSystem")

print("MyFirstMod 服务端已加载!") # print打印的内容将输出在MCStudio的 日志与调试工具 中

@Mod.InitClient()

def clientInit(self): # 这个方法名可以随便取,因为已经通过@Mod.InitClient()注明是客户端的初始化方法

clientApi.RegisterSystem("MyFirstMod", "MyClientSystem", "myScript.MyClientSystem.MyClientSystem")

print("MyFirstMod 客户端已加载!") # print打印的内容将输出在MCStudio的 日志与调试工具 中BP/myScript/MyServerSystem.pypythonimport mod.server.extraServerApi as serverApi

ServerSystem = serverApi.GetServerSystemCls()

# 继承 ServerSystem 类,表示这是一个 服务端System

class MyServerSystem(ServerSystem):

def __init__(self, namespace, systemName):

super(MyServerSystem, self).__init__(namespace, systemName)

print("MyServerSystem Hello World!") # print打印的内容将输出在MCStudio的 日志与调试工具 中BP/myScript/MyClientSystem.pypython# 本教程中,我们还暂时用不到 ClientSystem,但是我们可以先创建好

import mod.client.extraClientApi as clientApi

ClientSystem = clientApi.GetClientSystemCls()

# 继承 ClientSystem 类,表示这是一个 客户端System

class MyClientSystem(ClientSystem):

def __init__(self, namespace, systemName):

super(MyClientSystem, self).__init__(namespace, systemName)

print("MyClientSystem Hello World!")BOOM!就这么简单!

💡 为什么需要这些System?🧩 为什么需要两个系统(System)?用餐厅来理解! ​想象一下游戏就像一家餐厅:

服务器系统 = 厨房(决定食物实际内容)客户端系统 = 餐厅前厅(呈现给顾客看到的体验)👨‍🍳 服务器系统:游戏的"厨房" ​职责: 决定游戏中真正发生了什么简单理解: 计算伤害(怪物真的死了吗?)决定方块是否被破坏控制物品掉落存储真实的游戏数据👨‍💼 客户端系统:游戏的"前厅" ​职责: 让玩家看到并互动简单理解: 显示画面和声音处理你的鼠标点击和按键播放爆炸、火焰等特效展示菜单和界面📮 系统间如何交流:像传纸条一样 ​当你在游戏中点击方块,发生了什么?

⚠️ 为什么不能混在一起? ​就像餐厅里顾客不能随便进厨房一样:

❌ 客户端不能直接修改游戏数据(否则会作弊)❌ 服务器不负责播放声音和动画(它只关心真实数据)🌟 简单例子:击打树木得钻石 ​简化理解版 ​你点击树木(客户端检测到)客户端发消息:"嘿,服务器,玩家点击了这棵树"服务器决定:"好,我给他一颗钻石"服务器通知客户端:"请在玩家背包里显示一颗新钻石"客户端更新画面:你看到钻石出现在背包里🔑 记住这个简单规则 ​想象游戏是一部电影:

服务器是导演(决定故事情节)客户端是摄像机和屏幕(展示给观众看)记住:服务器决定发生什么,客户端决定如何展示!

💡 初学者提示 ​如果遇到问题,先问自己:

"这个功能应该由谁负责?是真实游戏规则还是显示效果?""我需要发送什么消息让另一边知道?"学会这种思考方式,你的Mod就能正确运行啦!

🎀 那么总结一下吧! ​核心架构:客户端-服务器分离 ​双系统模型的必要性 ​服务器系统 (ServerSystem) ​职责: 维护游戏的"真实状态"具体功能: 处理游戏核心逻辑(如战斗计算、物品掉落)管理AI行为与路径寻找执行世界生成与物理规则拥有数据的最终决定权客户端系统 (ClientSystem) ​职责: 处理玩家的直接体验具体功能: 渲染游戏画面与UI界面处理玩家输入播放音效与粒子效果进行预测性渲染(平滑过渡)系统间通信的关键:事件机制 ​事件驱动设计的优势 ​松耦合: 系统间无需直接相互调用可扩展: 多个系统可响应同一事件清晰职责: 服务端决定结果,客户端呈现效果实例:击打方块流程 ​客户端: 检测到玩家点击方块,发送BlockUseEvent服务端: 接收到事件,判断方块是否可被破坏更新方块状态,计算掉落物客户端: 播放方块破坏动画和音效显示掉落物常见问题与最佳实践 ​避免的错误模式 ​❌ 在客户端直接修改游戏状态❌ 在服务端处理UI渲染逻辑❌ 遗漏事件监听导致功能不同步最佳实践 ​✅ 服务端验证所有游戏逻辑(防作弊)✅ 合理使用自定义事件进行系统间通信✅ 保持客户端代码专注于视觉体验优化✅ 在事件参数中携带足够的上下文信息跨系统通信示例 ​python# 服务端发送自定义事件到客户端

def spawn_special_effect(self, position):

comp = serverApi.GetEngineCompFactory().CreateGame(serverApi.GetLevelId())

comp.NotifyToClient(player_id, "ShowSpecialEffect", {"position": position})

# 客户端监听并处理

def listen_events(self):

self.ListenForEvent("MyMod", "MyServerSystem", "ShowSpecialEffect",

self, self.on_special_effect)

def on_special_effect(self, event_data):

pos = event_data["position"]

# 在客户端显示特效...通过掌握客户端-服务端分离的设计模式,你将能够创建更稳定、可扩展且性能优秀的Mod。记住:服务端决定发生什么,客户端决定如何展示。

3. 运行你的Mod ​保存你的代码在 MCStudio 中找到此 Addons,鼠标划上去后点击 开发测试 按钮选择一个合适的游戏版本(一般为最新)填写相关测试名称和测试地图的配置,点击 开始 按钮等待游戏启动,你会在 脚本与测试工具 看到 MyFirstMod 服务端已加载! 和 MyFirstMod 客户端已加载! 的输出🤔 常见问题如果你没有看到期望的输出,可以在 脚本与测试工具 中查看日志,看看有没有报错如果没有任何报错,你需要检查你的 脚本目录 及以下的各级目录中,是否有__init__.py文件,如果没有,可以手动创建一个空文件再次检查后,可以尝试重启游戏(右侧 测试存档记录)4. 实现简单功能 ​🧪 小功能:右键方块,获得钻石 ​BP/myScript/MyServerSystem.pypythonimport mod.server.extraServerApi as serverApi

ServerSystem = serverApi.GetServerSystemCls()

# 继承 ServerSystem 类,表示这是一个 服务端System

class MyServerSystem(ServerSystem):

def __init__(self, namespace, systemName):

super(MyServerSystem, self).__init__(namespace, systemName)

# 监听玩家使用方块事件

self.ListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(), "ServerBlockUseEvent", self, self.onBlockUse)

def onBlockUse(self, args):

# 从事件的参数中,获得玩家ID

playerId = args["playerId"]

# 生成(获取)一个引擎的ItemComponent

itemComp = serverApi.GetEngineCompFactory().CreateItem(playerId)

# 向玩家背包中放入一个钻石

itemComp.SpawnItemToPlayerInv({

"itemName": "minecraft:diamond",

"count": 1

})🔌 使用到的相关API

接口:ListenForEvent事件:ServerBlockUseEvent接口:SpawnItemToPlayerInv太棒了!赶快进入游戏,右键点击任意方块,你将获得一个钻石!