教程:制作数据包
本教程介绍如何制作数据包。数据包允许玩家添加或修改函数、战利品表、世界结构、进度、配方、谓词、标签、维度和自定义世界生成等Minecraft游戏内容。
准备工作[编辑 | 编辑源代码]

本节主要内容为安装VSCode软件及配置相应插件。VSCode是如今很多数据包玩家都常用的编辑软件,可以很方便地安装插件,有些插件可极大提升编辑体验。
点击以上链接进入官网后,点击左下角的“Download for”按钮以安装官网所推荐的VSCode版本。右上角的“Download”按钮可以手动选择要安装的VSCode平台版本。
关于更详细的安装细节,在此不过多阐述。
安装完成后,打开VSCode。如果你的界面语言为英文,可以在侧边栏找到“Extension”图标,点击后在展开区域上方的输入框中输入“Chinese”,找到“Chinese (Simplified) ”(简体中文)或“Chinese (Traditional) ”(繁体中文)并点击“Install”按钮以安装中文语言套件。
依然是点击侧边栏的“Extension”(插件)图标,在搜索框中输入“mcfunction”,找到“syntax-mcfunction”插件,点击“Install”(安装)按钮安装。该插件可渲染.mcfunction函数文件语法高亮。
创建数据包[编辑 | 编辑源代码]
要创建数据包,请首先找到世界存档文件夹中的datapacks
文件夹。世界文件夹的具体位置与你所使用的操作系统和世界类型有关。
数据包的所在位置[编辑 | 编辑源代码]
进入游戏,在单人游戏“选择世界”界面,选中一个世界,点击左下角的“编辑”按钮,在“编辑世界”界面中,点击“打开世界文件夹”按钮,即可打开你所选世界的存档文件夹。找到datapacks
文件夹,该文件夹即为存档数据包文件夹,其中可以存放若干个属于该世界的数据包。在datapacks
文件夹中,新建一个文件夹,该文件夹即你所创建的数据包,其名称可以灵活指定。
例如:
<世界存档文件夹>
datapacks
Test
- 该例即创建了一个
Test
数据包文件夹。
组织目录结构[编辑 | 编辑源代码]
数据包必须具有游戏所规定的文件夹结构。数据包中的每一项内容都有它自己的“家”。
以前文的Test
数据包为例,其内部的目录结构应如下所示:
Test
pack.mcmeta:数据包元数据文件。该文件是唯一必须存在的文件。
pack.png:该数据包的图标,用来显示在“选择数据包”界面中。
data
其中,pack.mcmeta
是数据包所必须的文件,因为Minecraft通过该文件识别数据包。
现在,我们选择之前所创建的Test
文件夹,将其使用VSCode打开(你可以直接拖拽到空的VSCode工作区中),这样便能在VSCode工作区中打开该文件夹。接下来我们只需要点击工作区的图标“New File”(新建文件)以及“New Folder”(新建文件夹)创建文件和文件夹即可。

注意,数据包中的命名空间、路径、文件夹名和文件名应仅包含以下符号:
0123456789
数字abcdefghijklmnopqrstuvwxyz
小写字母_
下划线-
连字号(减号)/
正斜杠(不能用于命名空间).
句号(不能用于命名空间)
首选命名格式为以下划线隔开的小写字母单词(lower_case_with_underscores
),称为蛇形命名法(lower snake case)。
本教程中使用test
作为data
中的新增的命名空间(你可以根据你的喜好使用其他名称,但是请使用英文和下划线,不要出现其他字符)。最重要的是,请让命名空间保持独特性,这样可以最大限度地防止数据包冲突。如果实在想不出好的命名空间,不妨使用你的游戏ID。
以上便完成了数据包基本文件夹结构的创建。
添加注册内容[编辑 | 编辑源代码]
添加的函数、进度等文件名也必须仅包含前文所述的符号,否则无法成功加载这些文件。
数据包可为游戏内的一些注册表注册相应内容,比如函数、战利品表、进度等。这里以添加函数文件为例,首先应确定函数注册表所对应的数据包路径,该路径即命名空间目录下的路径。函数注册表所对应的数据包路径为function
,所以数据包文件结构将如下所示:
Test
pack.mcmeta
data
test
function
如果某注册表所对应的数据包路径为abc/def/ghi
,那么应顺次在命名空间目录中递归添加3个目录。
添加按照注册表对应的数据包路径添加好相应文件夹后,就可以继续添加相应的文件了:
Test
pack.mcmeta
data
test
function
a.mcfunction
very_good_function
a123b.mcfunction
你可以任意增加或组织子文件夹,只不过在调用时书写命名空间ID会更长罢了。
安装辅助插件[编辑 | 编辑源代码]
请确保已经按照前文步骤安装了“syntax-mcfunction”插件。因为接下来要安装的插件依赖于该插件。
在插件搜索框中搜索“datapack”,找到“Datapack Helper Plus by Spyglass”,点击“Install”(安装)按钮安装。
如果在初始化Spyglass时弹出连接错误提示,则可参考如下解决方法:
进入网址https://tool.chinaz.com/dns
,点击“查询DNS”,输入raw.githubusercontent.com
,在查询出的“解析内容”中选择一个地址复制。
然后在你的操作系统中找到hosts
文件。Win11系统中,该文件位于C:\Windows\System32\drivers\etc
。你可以右键hosts文件,选择“用VSCode”打开。在hosts文件中添加你刚才复制的地址,并随后加上raw.githubusercontent.com
。例如:
185.199.111.133 raw.githubusercontent.com
同样方法,继续添加github.com
的DNS解析地址:
185.199.111.133 raw.githubusercontent.com 20.205.243.166 github.com
然后按Ctrl+S保存。此时如果弹出无法保存的提示,请选择“Retry as Admin”(以管理员权限重试),之后便成功保存。
为了确保插件初始化正常,之后应点击“Datapack Helper Plus by Spyglass”的齿轮图标,选择“Uninstall”(卸载)以卸载插件,然后再次安装。
现在,在前文所述的test
命名空间中新建一个test.mcfunction
函数文件:
提示:你可以直接在test
目录下输入function/test.mcfunction
来新建该函数文件。

Test
data
test
function
test.mcfunction
pack.mcmeta
在函数中键入命令,看看是否会有自动补全提示框出现。如果没有任何影响,或依然出现插件错误提示,可以在你的工作区根目录中添加一个spyglass.json
文件:
TEST
spyglass.json
data
test
function
test.mcfunction
pack.mcmeta

spyglass.json
{
"env": {
"env": "jsDelivr"
}
}
然后再关闭VSCode,重新进入。若等待一段时间后插件依然报错后无法正常使用,则卸载“Datapack Helper Plus by Spyglass”插件,重复该章节的步骤。
pack.mcmeta[编辑 | 编辑源代码]
在VSCode工作区中,选中pack.mcmeta
并打开,粘贴如下内容:

pack.mcmeta
{
"pack": {
"pack_format": 48,
"description": "§6教程数据包",
"supported_formats": [26, 48]
}
}
你也可以对照数据包 § pack.mcmeta中的字段在VSCode中自动补全相关字段(自动补全由之前所安装的DHP插件提供)。默认情况下,按Tab ↹即可自动补全提示框中的所选字段。
- 第3行,pack_format表示数据包所适用的Minecraft版本,版本通过pack_format后的整数——版本编号来表示。但是要注意,如果数据包的版本编号与当前游戏版本不兼容,游戏只会在数据包选择界面发出相应提示——数据包仍可以被加载,游戏并不会做强制要求。所以这个编号实际上仅用于提醒使用数据包的玩家。
- 关于各pack_format的编号所对应的游戏版本以及相关更改,可查看数据包/版本页面。
- 第4行,description字段即是数据包的描述性信息,它的值可以是文本组件或任意字符串。你也可以直接使用“§”符号(Minecraft格式化代码)来渲染颜色或添加粗体等格式。
- 当你将鼠标悬停在
/datapack list
命令所列出的数据包名上,或当你进入创建世界的数据包选择界面后,游戏将会显示description字段的内容。
- 当你将鼠标悬停在
- 第5行,对于数据包版本编号大于等于16的Minecraft版本(即1.20.2快照23w31a以上的版本),还可添加一个可选的supported_formats字段。该字段对原本的pack_format字段进行了扩充——除了可表示该数据包所适用的单个版本,还能表示所适用的最小或最大版本。这里的
[26, 48]
表示该数据包适用于版本编号大于等于26且小于等于48的Minecraft游戏版本。注意,supported_formats所定义的范围必须将pack_format编号包含在内。- 在旧版本中,该字段可能会被忽略,所以你只能将其视作一个带pack_format的“普通”的单版本数据包。因此,你无法通过设置supported_formats来向下“兼容”旧版本。
如果你觉得创建好了pack.mcmeta
文件,接下来应测试游戏是否能读取它。
- 打开Minecraft,进入世界。如果你已经在世界中,请在聊天栏执行
/reload
命令。这一步是为了让游戏读取数据包。 - 执行
/datapack list
命令,此时聊天框应该显示所有被禁用和被启用的数据包。当你将鼠标悬停在数据包名称上时,你应该会看到数据包的描述,即你在pack.mcmeta
的description中所写的内容。
具体效果:
如果/datapack list
命令执行后没有看到你的包,请检查:
- 是否保存了
pack.mcmeta
文件。若未保存,则该文件可能为一个不包含任何内容的空文件,游戏将不会读取到任何关于数据包的内容。 - 是否保证了
pack.mcmeta
文件的JSON语法正确。一般情况下,JSON语法错误会直接在配置好插件的VSCode中以红色标示出来。你应检查是否缺漏大括号{}
、逗号,
、冒号:
,双引号""
,方括号[]
。请记住,对于每个左大括号、双引号或方括号,必须有一个右大括号、双引号或方括号与之配对;JSON中的每一个字段名都必须被双引号包括(这可不是SNBT!)。
.mcfunction函数文件[编辑 | 编辑源代码]
函数是一系列顺次执行的命令。如果你还不熟悉各种命令的格式,建议参照各命令子页面的示例,在游戏内运行后查看实际效果。在数据包中,函数以函数文件的形式存在,文件中的每一行都可代表一条完整的命令。
函数文件必须在命名空间目录下的function
目录或其子目录中。在1.21及以上版本,函数文件夹是function
而非functions
。函数文件的后缀名必须是.mcfunction
,在正在运行的世界中可通过/reload
命令重新加载。以下是一个函数示例:

data/test/function/test.mcfunction
# 发出提示
say 运行中...
# 传送执行者到执行坐标向Y轴正方面偏移10格的位置。
execute as @s run tp @s ~ ~10 ~
每个函数可以看做一系列从上到下依次执行的多条命令。在同一个函数内,每条命令的起始位置都有相同的命令上下文参数(参阅命令上下文 § 行为)。对于原版数据包函数的问题可归结为如何控制这些环境参数的问题(在社区中有很多玩家将命令上下文称为执行环境)。数据包函数的核心命令为/execute
,读者可以结合命令上下文条目中的介绍进行实际操作,这样更易理解其内涵。
在行与行之间,可新增以#
开头的注释行,以记录编写思路。在读取函数时,注释行会被忽略,所以不用担心注释内的内容是否会出现读取问题。如果你准备将你的数据包分享给其他数据包用户,并且他们有可能阅读你的函数代码,则可添加更为详细的注释。
在VSCode的DHP插件支持下,你可以用不同数量的#
开头以对注释进行分层。对于几行连续的注释,会将其中开头#
数量最多的注释渲染为粗体。比如:

data/test/function/test.mcfunction
## 这是一段示例(本行注释文字将会被加粗)
say 1
### 这是另一段示例(本行注释文字将会被加粗)
## 这是该段示例的子部分
# 这是该段示例的一个二级子部分
execute as @s run tp @s ~ ~10 ~
要注意,虽然聊天栏中的命令可以带前导斜杠,但在函数中这是不允许的:
# 在函数中这样写会报错
/execute as @s run tp @s ~ ~10 ~
如果一个函数文件中的某条命令无法解析,则会导致其所在的整个函数无法运行。例如以下函数:

data/test/function/test.mcfunction
say Hi
tp @s ~ ^ ~
setblock ~ ~ ~ diamond_block
虽然该函数文件所在的路径正确,但由于其中的tp
命令有语法错误(相对坐标和局部坐标混用)——不仅是错误的那一行,其中的所有语句都会失效。
有时候,你需要在函数中书写大量的SNBT:
give @s stick[consumable={animation:"crossbow", consume_seconds:2.0, has_consume_particles:false, sound:"block.anvil.break"}]
将给予玩家一个木棍,该木棍挂载了一个consumable
组件,组件的具体数据以SNBT表示。显然,这种书写方式比较拥挤,在阅读时也不够清爽,不妨写为下面这种格式:
give @s stick[consumable={\
animation:"crossbow", \
consume_seconds:2.0, \
has_consume_particles:false, \
sound:"block.anvil.break" \
}\
]
添加换行和缩后就很容易看出SNBT的结构了。但是要注意,行之间必须添加反斜杠来进行承接。
有些时候,我们希望命令中的某些部分是运行时可变的。比如,我们希望给予一个和玩家当前主手所选中的物品的ID一样的物品。你可能会想到用以下的穷举方法:
execute if items entity @s weapon.mainhand minecraft:acacia_boat run give @s minecraft:acacia_boat
execute if items entity @s weapon.mainhand minecraft:acacia_button run give @s minecraft:acacia_button
# ... 此处省略若干对物品ID的穷举
显然,这种方法效率很低,而且将带来极大的工作量。以上命令其实都具有同一种结构:execute if items entity @s weapon.mainhand <物品ID> run give @s <物品ID>
——将命令中的某一个部分暂时使用一个未知量来填充:

data/test/function/macro_test.mcfunction
$execute if items entity @s weapon.mainhand $(id) run give @s $(id)
这里的未知量$(id)
中的名称是可以自定义的,但是要注意,括号中的名称不能使用中文或其他符号。具体允许的符号可参考该章节所对应的主条目。
接下来,只需要获取玩家主手物品的ID即可。因为我们可以直接传递主手物品ID到以上的宏函数中,$(id)
将被替换为传入的物品ID:
# 将玩家手持物品ID存储在xclib:data这个命令存储的arg.id标签中
data modify storage xclib:data arg.id set from entity @s SelectedItem.id
# 将xclib:data命令存储的arg复合标签传递给宏函数
function test:macro_test with storage xclib:data arg
为了将参数传递给宏函数,必须先将参数封装进一个复合标签。在成功获取到玩家手持物品ID后,命令存储的SNBT可能为:
{arg:{id:"minecraft:apple"}}
表示为树状图:
-
- arg
- id:
minecraft:apple
- id:
- arg
显然,这里的id与宏函数中的id
匹配:

data/test/function/marco_test.mcfunction
$execute if items entity @s weapon.mainhand $(id) run give @s $(id)
最终宏函数将变为一条普通命令:

data/test/function/marco_test.mcfunction
execute if items entity @s weapon.mainhand minecraft:apple run give @s minecraft:apple
虽然宏函数让命令变得非常灵活,但是要注意,宏函数有较高的额外开销,可能对性能造成很大影响。在服务器中也要谨慎使用宏函数,使用时必须考虑宏函数所带来的副作用。
在游戏规则sendCommandFeedBack
为true且每次以玩家的身份运行函数(玩家主动运行或通过/execute
)时,均会返回一行“已执行函数example:test中的x条命令”。在某些场景下,你可能并不希望玩家看到这条信息,将这条规则手动设置为false即可。另外,如果你使用循环型命令方块高频执行某个函数时可能会收到大量命令方块消息,此时通过命令/gamerule commandBlockOutput false
关闭即可。
在函数中允许通过function
命令来调用其他函数,也可以直接调用自己。核心的要点是,被调函数会继承原来的执行环境(继承命令上下文参数)。
如下,在该函数中,先使用execute
命令改变上下文参数中的执行者为“距离执行位置最近的一个实体”,然后调用了另一个函数:

data/test/function/call_other_function.mcfunction
say 在主调函数中,我是:@s
execute as @n run function test:func1

data/test/function/func1.mcfunction
say 在被调函数中,我是:@s
如果你在世界中的某个位置放置命令方块,并设置命令然后启动命令方块:
则会看到输出的两个名称都是相同的(如果找不到这输出为空)。
如果改为调用自己:(这被称为递归执行)

data/test/function/call_other_function.mcfunction
execute as @n run function test:call_other_function
则会发生瞬间(1刻内)的多次循环。你会看到聊天栏输出大量的“在主调函数中,我是:XXX”——该函数递归并且无条件地执行,直到累计达到单刻最大命令数后终止执行。所以对于递归函数,一定要考虑递归边界(让递归终止的条件),防止递归函数的执行次数过多——这会造成函数性能被极大消耗。
在VSCode中,DHP插件提供了函数跳转功能。只需要指向/function
命令后的函数命名空间ID,按住Ctrl的同时点击鼠标左键即可。

读者可参考如下的视频练习一下创建数据包到使用VSCode编写函数并运行函数的整个过程:
另外,如果你学过一些编程语言,前文的函数文件其实可以大概描述为如下的Python风格伪代码:
def test:test(flag) -> int:
say 运行中...
execute as @s run tp @s ~ ~10 ~
# 发现魔法羊
execute if entity @e[tag=magical_sheep,limit=1] run \
function test:found_magical_sheep()
exec(f'''execute if score #{flag} var matches 0 run return fail''')
return 1
.json文件[编辑 | 编辑源代码]
注意:诸如魔咒、盔甲纹饰图案、盔甲纹饰材料等都无法直接通过/reload
命令来重新加载。你应通过重进世界来加载。
在数据包中,.json文件占据了很大一部分,比如进度、战利品表、配方、魔咒等。
在编写时,推荐的方式是先解压相应版本的原版.jar包,从解压后的.jar包中找到data
文件夹,该文件夹即原版数据包的data
文件夹。在编写任何一个JSON文件时,你都可在其中找到相应的文件作为参考范例,同时对照wiki中的数据格式页面进行修改或扩充。
如果你不知道哪些文件可以是JSON文件,可以参考数据包 § 文件夹结构。你只需要确保相应的JSON文件在其目录或子目录中即可。
.nbt结构文件[编辑 | 编辑源代码]
结构可以用于结构方块或拼图方块,也可以覆盖Minecraft中原版结构的外观。结构以NBT格式存储,你可以使用结构方块创建NBT文件。MCEdit之类的第三方软件也可以导出NBT文件。
当你使用结构方块成功保存一个结构后,在.minecraft/saves/temp/generated/test/structures/
目录及其子目录下,可以看到你保存的.nbt文件。例如,我在结构方块所输入的结构名为test:bar
,那么保存后的结构文件路径为:.minecraft/saves/temp/generated/test/structures/test/bar.nbt
。
在你的命名空间文件夹中,你可以创建structure
文件夹,然后放入刚才通过结构方块保存的结构文件。
开发工具和实用程序[编辑 | 编辑源代码]
现在有很多的工具可以帮助你更容易地编写数据包。以下列表包含了一些转换器以及语法高亮插件相关的软件工具。对于这些第三方的程序,要谨慎安装——这些程序并没有受到严格监控,可能包含恶意软件。
名称 | 支持的IDE或编辑器 | 描述 | 所支持的最新游戏版本 |
---|---|---|---|
syntax-mcfunction | Visual Studio Code以及Sublime Text | 提供函数文件的语法高亮 | 1.21 |
Datapack Helper Plus by Spyglass | Visual Studio Code | 提供了语法补全、语法错误检查和目标选择器性能提示 | 1.21 |
Datapack Icons | Visual Studio Code | 一个比较花俏的,带有minecraft风格图标的主题,专为数据包开发者设计 | 1.21 |
Minecraft Command DevKit | IntelliJ IDEA | 满足了模组和函数文件的协同调试需求 | 1.21 |
MCFunction.xml | Notepad++ | 语法高亮 | 1.13.3 |
名称 | 描述 | 所支持的最新游戏版本 |
---|---|---|
Beet | Minecraft包开发工具和基于Python的转义器。 | 1.20.6 |
MC-build | 数据包预编译语言 | 1.21 |
Sandstone | Typescript语言的Minecraft数据包库 | 1.20.6 |
TMS Transpiler | 一个Python工具,可以将带缩进的函数代码汇编为数据包中的有效文件。 | 1.21 |
ObjD | 数据包构建框架,旨在尽量减少数据包开发中的重复性工作。 | 1.20.4 |
Minity | 另一种可编译为数据包的脚本语言,使用Node.js编译器。 | 1.18 |
Minecraft Script | 基于JavaScript的语言,可以通过Node.js编译器被编译为处于工作状态中的数据包。 | 1.13.3 |
名称 | 类型 | 描述 | 所支持的最新游戏版本 |
---|---|---|---|
Misode's Data Pack Generators | Website | 面向Minecraft数据包的JSON生成器 | 1.21 |
MCStacker | Website | 一个命令生成器集合 | 1.21 |
MCreator | Program | 一个易于使用,功能齐全的图形工具,用于创建数据包和模型。 | 1.20.4 |
MCDatapacker | Program | 一个用于创建和编辑数据包的离线程序 | 1.20.4 |
NBTData Pack Generator | Website | 一个在线生成器,用于没有任何功能的原始数据包框架。 | 1.20.2 |
Minecraft Recipe Generator | Website | 一个在线生成器,用于制作自定义配方。 | 1.20.1 |
Recipe Generator | Website | 一个在线生成器,生成合成所需的JSON文件。 | 1.20 |
Datapack Creator | Program | 一个IDE,用于使用一些有用的工具创建数据包。 | 1.17 |
Minecraft Tools Recipe Generator | Website | 一个在线生成器,用于生成合成所需的JSON文件。 | 1.12 |
Origin Creator | Website | 一个功能齐全的数据包web工具。 | 未知 |
参见[编辑 | 编辑源代码]
实例[编辑 | 编辑源代码]
导航[编辑 | 编辑源代码]
[隐藏] | |||||||||
---|---|---|---|---|---|---|---|---|---|
基本概念 | |||||||||
数据包 |
| ||||||||
资源包 | |||||||||
相关条目 | |||||||||
相关教程 | |||||||||
参考实例 |
|
[隐藏] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|