基础概念
在开始 Mod 开发之前,你需要理解《我的世界》基岩版(中国版)中的核心概念。这些概念贯穿整个开发过程——从 JSON 配置到 Python 脚本,几乎每一步都会用到它们。
世界与维度
世界(World) 是一个完整的游戏实例——一个存档文件或一个联机服务器就是一个世界。世界由地形、实体、方块等所有游戏内容组成。
区块
区块(Chunk) 是地图加载和卸载的基本单位,大小为 16 × 384 × 16 方块(Y 范围:-64 ~ 320)。
区块坐标计算:
X_chunk = Floor(X / 16)
Z_chunk = Floor(Z / 16)
区块 (X, Z) 的边界:
最小点 = (X * 16, -64, Z * 16)
最大点 = (X * 16 + 15, 320, Z * 16 + 15)玩家在世界中移动时,引擎会动态加载/卸载周围的区块。
未加载区块不可操作
如果目标方块或实体所在的区块还没有被加载,你的脚本无法读取或修改它们。在编写逻辑时需要考虑这一点。
维度
维度(Dimension) 是世界中的独立空间。原版包含三个维度:
| 维度 | ID | 说明 |
|---|---|---|
| 主世界(Overworld) | 0 | 默认维度 |
| 下界(Nether) | 1 | 熔岩地形,坐标压缩 8 倍 |
| 末地(The End) | 2 | 末影龙、末地城 |
中国版还支持通过 netease_dimension 配置自定义维度。
坐标系
我的世界使用右手坐标系:
- X 轴:东(+)/ 西(-)
- Y 轴:上(+)/ 下(-)
- Z 轴:南(+)/ 北(-)
Y = 0 不是地面高度——最低点为 Y = -64,海平面约在 Y = 63。
实体与生物
实体(Entity) 是世界中可区分的、有位置和行为的对象。实体分为两大类:
服务端实体
有 entityId,由服务端运算,会保存到存档:
- 生物(Mob) — 有生命值、可移动的实体,玩家也属于生物
- 物品实体 — 掉落在地面上的物品
- 方块实体 — 箱子、熔炉等有附加数据的方块
- 抛射物 — 箭矢、雪球等投射物
客户端实体
仅在客户端渲染,退出游戏后销毁:
- 粒子特效、序列帧动画、文字面板
entityId 与 __id__
在 Python 脚本中,服务端实体通过 entityId(字符串)标识。部分旧版 API 使用 __id__ 字段,它们指向同一实体。玩家实体同时拥有 playerId,本质上也是一个 entityId。
游戏刻
游戏刻(Tick) 是游戏逻辑的基本时间单位,正常情况下 1 秒 = 20 Tick。
- 每个 Tick 引擎执行一次逻辑更新(实体移动、方块更新、红石计算等)
- 脚本中的
Update()方法每 Tick 调用一次 - 服务器卡顿时,实际 TPS 可能低于 20
物品
物品(Item) 是玩家背包中或掉落在地面上的对象。在 Python 脚本中以 itemDict 字典表示:
# 物品信息字典(itemDict)
{
"newItemName": "minecraft:diamond_sword", # 物品标识符(必须)
"newAuxValue": 0, # 附加值(必须)
"count": 1, # 数量(必须),为 0 时表示空物品
"durability": 1562, # 耐久度(可选)
"enchantData": [(9, 1)], # 附魔数据(可选): (EnchantType, 等级)
"modEnchantData": [("my_enchant", 2)], # 自定义附魔数据(可选)
"customTips": "", # 自定义提示文本(可选)
"extraId": "", # 自定义标识符(可选)
"userData": {} # 自定义 NBT 数据(可选)
}关于旧版字段
itemName 和 auxValue 已弃用。新开发请始终使用 newItemName 和 newAuxValue。
customTips 支持格式占位符,可自由组合:
| 格式字符串 | 说明 |
|---|---|
%name% | 物品名 |
%category% | 物品类型 |
%enchanting% | 附魔属性 |
%attack_damage% | 攻击伤害 |
附魔信息字典
附魔数据在 itemDict 的 enchantData(原版附魔)和 modEnchantData(自定义附魔)中传递。自定义附魔的注册信息通过以下字典描述:
| 字段 | 类型 | 说明 |
|---|---|---|
identifier | str | 自定义附魔 ID |
description | str | 对应 zh_CN.lang 中的语言键 |
primary_slots | list(str) | 附魔槽位,如 ["sword", "bow"] |
cost | list(int) | 各等级经验消耗,长度 = max_level |
max_level | int | 最大附魔等级(默认 1) |
frequency | str | 稀有度:common / uncommon / rare / very_rare |
is_treasure_only | bool | 是否宝藏型(不在附魔台出现) |
is_discoverable | bool | 是否可在附魔台发现 |
is_lootable | bool | 是否可在战利品表出现 |
is_curse | bool | 是否诅咒(不可通过砂轮移除) |
incompatible | list(str) | 冲突附魔名称列表 |
记分板字典
记分板在脚本中通过两种字典表示:
记分准则字典(scoreDict):
| 字段 | 类型 | 说明 |
|---|---|---|
displayName | str | 记分项显示名称 |
name | str | 记分项名称 |
criteriaName | str | 记分准则类型(基岩版仅支持 dummy) |
value | int | 玩家分数(仅获取玩家分数时有此字段) |
玩家记分项字典(playerScoreDict):
| 字段 | 类型 | 说明 |
|---|---|---|
playerId | str | 玩家 ID |
scoreList | list(scoreDict) | 该玩家所有记分准则及分数 |
方块
方块(Block) 是组成世界地形的基本单位,占据 1×1×1 的立方体空间。在脚本中以 blockDict 字典表示:
# 方块信息字典(blockDict)
{
"name": "minecraft:wool", # 方块标识符(必须)
"aux": 1 # 附加值(可选,默认 0)
}方块状态
一种方块可能存在多种状态(如不同颜色的羊毛)。相比 aux 附加值,方块状态更具可读性:
{
"name": "minecraft:wool",
"states": {
"color": "orange"
}
}查看方块状态
可在游戏内调用 GetBlockStates 接口查看方块状态,也可参阅 Microsoft 文档 - Block States。
方块基本信息字典
通过 GetBlockBasicInfo 接口可获取方块的基本属性信息(blockBasicDict):
| 字段 | 类型 | 说明 |
|---|---|---|
blockLightAbsorption | int | 方块透光率(0~15) |
blockLightEmission | int | 方块发光等级(0~15) |
explosionResistance | float | 爆炸抗性 |
destroyTime | float | 摧毁时间 |
solid | bool | 是否实心(影响窒息伤害) |
pathable | bool | AI 寻路时是否视为障碍物 |
fireResistant | bool | 掉落物是否防火 |
renderLayer | int | 渲染材质层 |
creativeCategory | int | 创造栏分类 |
loot | str | 掉落表路径(未配置时为空字符串) |
mapColor | str | 地图颜色(十六进制,未配置时为 "#0") |
tier | dict/None | 挖掘属性(仅配置了 netease:tier 的方块) |
unwalkable | bool | 生物是否不可在上方行走 |
breathability | int | 可呼吸性(需开启假日创造者功能) |
NBT 数据格式
原版方块实体数据和物品 userData 使用 NBT 格式存储。通过 Python 接口获取时,会进行类型转换:
| NBT 类型 | 转换后 Python 数据 |
|---|---|
| Byte | {"__type__": 1, "__value__": True/False} |
| Short | {"__type__": 2, "__value__": ShortValue} |
| Int | {"__type__": 3, "__value__": IntValue} |
| Int64 | {"__type__": 4, "__value__": Int64Value} |
| Float | {"__type__": 5, "__value__": FloatValue} |
| Double | {"__type__": 6, "__value__": DoubleValue} |
| ByteArray | {"__type__": 7, "__value__": IntList} |
| String | {"__type__": 8, "__value__": String} |
| List | {"__type__": 9, "__value__": ...(递归转换)} |
| Compound | {"__type__": 10, "__value__": ...(递归转换)} |
| IntArray | {"__type__": 11, "__value__": IntList} |
使用示例
# 从方块实体获取 NBT 数据
data = blockEntityData['myKey']
# 写入整数类型的 NBT
blockEntityData['score'] = {"__type__": 3, "__value__": 100}抛射物
抛射物(Projectile) 是受外力被抛射到空中飞行的实体,受重力与摩擦力影响。例如射出的箭矢、扔出的雪球、末影珍珠等。自定义抛射物通过 netease:projectile 组件配置,支持设置发射力量、重力、伤害、粒子等属性。
视觉表现术语
以下是开发中常见的视觉表现相关术语:
| 术语 | 说明 |
|---|---|
| 骨骼模型 | 使用 3ds Max、Blender 等建模软件制作的模型,与原版基于 cube 搭建的模型不同。生物、方块实体等都可以使用骨骼模型 |
| 序列帧 | 通过逐帧切换图片形成的动画效果,在游戏中表现为一个平面面片。常用于特效和 UI 动画 |
| 粒子 | 通过不断发射多个不同大小的平面面片形成的特效效果,可替换贴图材质模拟丰富的表现 |
| 文字面板 | 基于序列帧实现的文字显示,包括伤害飘字、实体头顶名称等 |
| UI | 用户界面,游戏和用户之间进行交互和信息交换的界面。通过 JSON UI 定义布局,通过脚本控制逻辑 |
Client-Server 架构
我的世界基岩版采用 Client-Server(客户端-服务端) 架构:
| 端 | 职责 | 示例 |
|---|---|---|
| 服务端(Server) | 游戏逻辑、数据权威 | 地形生成、生物 AI、物品逻辑、伤害计算 |
| 客户端(Client) | 渲染、用户输入 | 画面显示、动画播放、UI 交互、音效 |
即使在单人游戏中,本地也会运行一个内置服务端。开发 Mod 时,你的脚本分为 ServerSystem 和 ClientSystem 两部分,分别在不同端运行。
┌─────────────────────────────────────────────────┐
│ Server(服务端) │
│ - 地形生成 / 方块更新 │
│ - 生物 AI / 伤害计算 │
│ - 物品逻辑 / 存档读写 │
│ - ServerSystem(你的服务端脚本) │
├────────────── 事件通信 ──────────────────────────┤
│ Client(客户端) │
│ - 画面渲染 / 动画播放 │
│ - 用户输入 / UI 交互 │
│ - 音效播放 │
│ - ClientSystem(你的客户端脚本) │
└─────────────────────────────────────────────────┘为什么要分端?
游戏规则和数据由服务端权威管理,客户端只负责展示。这样即使客户端被篡改,也不影响游戏公平性。两端之间通过**事件(Event)**通信。详见 Client-Server 架构详解。
行为包与资源包
附加包(Addon)分为行为包(behavior_pack)和资源包(resource_pack):
- 行为包 — 放服务端需要的内容:实体定义、方块定义、物品逻辑、脚本、战利品表、配方等
- 资源包 — 放客户端需要的内容:模型、贴图、音效、UI、动画、粒子特效等
引擎启动时会从固定路径读取这些文件。你只需按规则把文件放在对应目录,引擎就会自动加载。
覆盖原版内容
附加包与原版数据包在加载时拥有同等地位,且附加包优先级更高。在附加包中放入同路径、同名文件即可覆盖原版内容(如替换泥土贴图)。
项目文件结构
下面是一个典型的地图类型作品的完整目录结构:
作品文件夹/
├── behavior_packs/ # 行为包集合
│ └── behavior_pack_xxx/ # 行为包
│ ├── entities/ # 实体行为定义(JSON)
│ ├── items/ # 原版物品定义(JSON)
│ ├── netease_items_beh/ # 🔶 中国版自定义物品(JSON)
│ ├── netease_blocks/ # 🔶 中国版自定义方块(JSON)
│ ├── loot_tables/ # 战利品表
│ ├── recipes/ # 配方(工作台、熔炉等)
│ ├── spawn_rules/ # 生物生成规则
│ ├── trading/ # 交易配置
│ ├── script_xxx/ # Python 脚本目录
│ │ └── Parts/ # 零件脚本链接(自动生成)
│ ├── Parts/ # 零件文件夹
│ │ └── myPart/
│ │ ├── myPart.part # 零件本体
│ │ ├── myPartPart.py # 零件脚本
│ │ ├── myPartPartMeta.py # 零件元数据
│ │ └── __init__.py
│ ├── Presets/ # 预设
│ ├── storyline/ # 逻辑编辑器文件
│ └── manifest.json # 行为包描述文件
│
├── resource_packs/ # 资源包集合
│ └── resource_pack_xxx/ # 资源包
│ ├── entity/ # 实体客户端定义(JSON)
│ ├── models/ # 模型文件(原版 + 骨骼模型)
│ ├── textures/ # 🖼️ 贴图资源
│ ├── netease_items_res/ # 🔶 中国版自定义物品客户端配置
│ ├── effects/ # 🔶 粒子 & 序列帧(JSON)
│ ├── sounds/ # 音效文件
│ ├── texts/ # 语言文件(.lang)
│ ├── ui/ # UI 界面(JSON)
│ ├── attachables/ # 装备模型
│ ├── materials/ # 材质文件
│ ├── font/ # 字体文件
│ └── manifest.json # 资源包描述文件
│
├── .db/ # 地图数据
│ └── presets.json # 预设存档
├── level.dat # 地图数据
├── levelname.txt # 存档名
├── world_behavior_packs.json # 使用哪些行为包
├── world_resource_packs.json # 使用哪些资源包
└── world_icon.jpeg # 存档图标中国版特有目录
标有 🔶 的目录是中国版特有的。netease_items_beh/、netease_blocks/、netease_items_res/ 等目录与原版国际版结构不同,请勿混淆。
贴图资源预算
资源包中所有图片的内存占用应控制在 100MB 以内。超出预算可能导致低端设备崩溃或加载失败。
manifest.json
每个行为包和资源包都需要一个 manifest.json 描述文件。它告诉引擎这个包是什么、版本多少、类型是什么。
{
"format_version": 2,
"header": {
"name": "我的自定义行为包",
"description": "这是一个示例行为包",
"uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"version": [1, 0, 0],
"min_engine_version": [1, 13, 0]
},
"modules": [
{
"type": "data",
"uuid": "f9e8d7c6-b5a4-3210-fedc-ba0987654321",
"version": [1, 0, 0]
}
]
}关键字段说明:
| 字段 | 说明 |
|---|---|
header.uuid | 包的唯一标识符,必须全局唯一 |
modules[].uuid | 模块的唯一标识符,必须与 header.uuid 不同 |
header.version | 包版本号,格式 [主版本, 次版本, 修订号] |
modules[].type | 包类型:data = 行为包,resources = 资源包 |
UUID 生成
每个 manifest.json 需要两个不同的 UUID(header 和 module 各一个)。可以使用 MC Studio 自动生成,也可在线生成:uuidgenerator.net。
命名规范
良好的命名规范能避免多个 Mod 之间的标识符冲突。
命名空间
命名空间(Namespace) 是标识符的前缀,格式为 namespace:name。
minecraft:stone # 原版内容,命名空间 = minecraft
team_modname:magic_wand # 自定义内容,命名空间 = team_modname| 来源 | 命名空间 | 示例 |
|---|---|---|
| 原版 | minecraft | minecraft:zombie, minecraft:diamond |
| 自定义 | 团队名_作品名 | tomato_island:emerald_staff |
不要使用 minecraft 命名空间
自定义内容禁止使用 minecraft 命名空间,否则会与原版内容冲突。命名空间在 MC Studio 创建作品时设置,一旦设定不建议更改。
标识符格式
| 类型 | 格式 | 示例 |
|---|---|---|
| 方块/物品/实体 ID | snake_case | my_mod:fire_sword |
| Python 类名 | PascalCase | MyServerSystem |
| Python 变量/函数 | camelCase | onPlayerAttack |
| 事件名 | PascalCase | PlayerAttackEvent |
| 文件/文件夹 | snake_case | custom_items/ |
命名建议
- 标识符只使用小写字母、数字和下划线
- 避免使用中文、空格或特殊字符
- 保持简短且有描述性:
fire_sword优于my_very_cool_sword_v2
下一步
理解了这些基础概念后,你可以继续探索:
- 创建你的第一个 Mod — 动手实践
- Addon 开发 — 深入了解附加包
- 自定义内容 — 自定义方块、物品、实体
- Python 脚本开发 — 编写游戏逻辑
- Client-Server 架构详解 — 理解双端通信
