本篇教程由作者设定使用 CC BY-NC-SA 协议。
简介
包的元数据(pack.mcmeta)是游戏识别包(资源包、数据包)的标识文件。请注意文件的拓展名为mcmeta,不要搞出“pack.mcmeta.txt”之类的东西显示文件拓展名的重要性。
资源包、数据包的根目录或解压后的根目录下必须包含写法正确的pack.mcmeta文件。如果写错,资源包将无法被加载,游戏将在日志中给出错误。
因为作者为资源包创作者,所以本教程只介绍资源包元数据写法。如果读者不熟悉JSON语法,请自行阅读Wiki的相关页面。
该教程以文本为主,所以请打起精神~
资源包格式化版本号
游戏本身有多个版本,例如1.20.2、1.21.6、26.1等。资源包需要在元数据中明确支持的版本——不过不是直接使用上述的游戏版本号,而是使用与游戏版本相对应的资源包格式版本号。
资源包格式版本号及其对应的版本参见Wiki。
另外,自1.21.9的第一个快照起,资源包格式版本号从原先的一个“整数”(例如55)变为了一个“小数”(例如65.2、69.0)。在前者中,这个“整数”即为主要版本号;在后者中,点号分割的两数分别为主要版本号和次要版本号(例如65.2的主要版本号是65,次要版本号是2,所以包含版本号的字段应该填写[65, 2]),不提供次要版本号则默认其为0(注意区分点号和逗号)。
下面关于资源包“版本”“版本号”等的内容都已在此说明。
写法及文件格式
原版所使用的所有mcmeta文件必须使用JSON格式(不能含注释),包括资源包元数据。
该标题以下的目录按JSON元素嵌套结构进行编排。为方便阅读,在字段名称前添加数字标号:数字越大,代表在树状结构的层级越高,根元素的标号为0。
下面是根元素下的字段:
1-pack
pack字段是一个元素,代表资源包基础元信息。
◇ 必须填写该字段。
该元素下有如下字段:
2-description
该字段表示资源包的描述文字。该字段是一个文本组件,可以在其中使用“§”开头的格式化代码(需要注意,格式化代码已被弃用,建议优先选择文本组件)。文本最多显示两行,过长会被截断。
◇ 必须填写该字段。
2-支持版本
有3个字段可以表示支持版本的区间,1个字段表示当前支持的版本。分别为:
min_format和max_format:
这两个字段分别表示资源包支持的最低版本和最高版本。为一个闭区间,于1.21.9 25w31a新增。两个字段写法基本一致。通常为包含两整数的数组,格式为:[主要版本号, 次要版本号]。
前者中,当字段值为一个数或一个包含一个数的数组时,默认已提供的数值为主要版本号,次要版本号为0。例如:75,[75] 和 [75, 0] 的写法是等价的。
后者中,当字段值为一个数或一个包含一个数的数组时,默认已提供的数值为主要版本号,次要版本号为最大的可能值(Wiki原文如此。应该为32位有符号int值的上限,即2147483647)。
supported_formats:
该字段有两种写法:
写作数组:此时的数组包含两个整数,表示支持的版本闭区间,无主次版本号之分。例如:[55, 64]。
写作一个包含两个字段的元素:此时包含min_inclusive和max_inclusive,均为整数,表示资源包支持的最低和最高版本,不可以使用min_format和max_format的数组写法,也就没有主次版本号之分。
pack_format:
该字段表示资源包支持的(特定)版本。
另外,例如65.2等的版本号,依照前文“资源包格式版本号”,数组应写作为 [65, 2],不可写成直接写成65.2或 [65.2]。
重要说明
supported_formats和pack_format字段在1.21.9 25w31a及以后被min_format和max_format取代,所以弃用。
如果主资源包支持的最低版本不低于1.21.9 25w31a,不可以填写前两个旧字段,否则会报错。反之则必须填写。
如果主资源包支持的最高版本低于1.21.9 25w31a(不包含),不可以填写后两个新字段。反之则必须填写。
1-overlays
该字段是一个元素,用于设置在特定格式版本下的叠加资源包。例如:26.1修改了兔子的实体模型和纹理,而某个资源包同时兼容26.1和26.1以下的版本,这时如果不想拆分资源包,就应该叠加一个适用于26.1及以上的资源包。
◇ 该字段非必需。
如果定义该字段,必须包含以下字段:
2-entries
该字段是一个数组,表示叠加资源包列表。
叠加资源包相当于主包内包含的小包,在特定版本覆盖特定内容。其文件结构与普通资源包一致,但目录下的元数据和图标会被忽略。叠加资源包不可以使用zip格式。
需要注意,该字段需保证顺序(见下方测试)。
◇ 如果定义overlays字段,必须填写该字段集齐以下的内容。
3-一个元素
该元素包含以下字段:
4-directory
该字段是一个字符串,表示叠加资源包相较于资源包根目录的位置。例如:“26_1”、“.../1_21_6”等(注意最前面不要加“/”!)。
◇ 必须填写该字段。
4-支持版本区间
与前文pack元素中的相关内容基本一致。
有三个字段表示支持的版本区间:
min_format和max_format:格式与上文pack字段中的min_format和max_format完全一致。
formats:该字段融合了上文pack字段中pack_format和supported_formats的写法。
◇ 这些字段非必需。
重要说明
如果资源包整体支持1.21.9 25w31a以下的版本,也必须填写叠加资源包的formats字段,即使叠加资源包仅适用于1.21.9 25w31a及以后。如果任意叠加资源包支持1.21.9 25w31a以下的版本,则必须在其中填写formats字段,不写会报错。如果没有上述两个条件均不满足,则不可以填写formats字段,否则会报错。
-叠加资源包顺序测试
为说明叠加资源包的读取顺序,我在测试资源包根目录下定义a和b目录,在其下的<a和b>/minecraft/textures/block/iron_block.png放入两张略有不同的内容。修改过的贴图为:
| b目录下的贴图 |
先在pack.mcmeta填写如下内容:
{
... ,
"overlays": {
"entries": [
{
"directory": "a",
"formats": 64
},
{
"directory": "b",
"formats": 64
}
]
},
...
}结果如图所示:
先读取b包,因此显示标“B”的贴图
再将两directory字段的值互换,重新加载资源包:
先读取a包,因此显示标“A”的贴图
可以这样理解。游戏从上到下读取叠加资源包,先读取的内容被后读取的覆盖。(与加载资源包界面的上下优先级顺序正好相反)
1-language
该字段为一个元素,表示自定义添加的语言(一个包)。
2-"一个语言代号"
该字段为一个元素,是添加的语言的代号,长度1~16个字符。游戏会读取资源包/assets/<命名空间>/lang/<这个语言代号>.json语言文件并加载。
该元素需要包含以下字段:
3-bidirectional
该字段为一个布尔值,表示该语言是否从右往左书写,默认为false(即从左往右)。
◇ 该字段非必需。
3-name
该字段为一个非空字符串,代表该语言的完整名称。
◇ 如果定义上述字段,必须填写该字段。
3-region
该字段为一个非空字符串,代表该应用该语言的国家名称。
◇ 如果定义上述字段,必须填写该字段。
-language字段实例
pack.mcmeta内元素如下:
{
... ,
"language": {
"simp_wenyan": {
"name": "简体文言",
"region": "华夏"
}
},
...
}加载资源包(实际应用时记得定义语言文件),结果如下:
可以看到语言已被添加1-filter
该字段为一个元素,代表需要下层资源包中需要过滤的内容。
◇ 该字段非必需。
2-block
该字段为一个包含若干元素的数组,指定需要过滤的内容列表。
◇ 如果定义上述字段,必须填写该字段。
3-一个元素
该元素内可以包含两个字段,如果该元素为空,表示完全过滤下层资源包的所以内容。
4-namespace
该元素是一个字符串,内容为一个正则表达式,匹配过滤符合的命名空间。
正则表达式具体写法详见微软的《正则表达式语法》。有点老,但我应该可以用吧?
◇ 该字段非必需。
4-path
该元素是一个字符串,内容为一个正则表达式,匹配过滤符合的路径。
◇ 该字段非必需。
-filter实例
这里先验证正则表达式的反斜杠是否需要进行转义,即把字符串写成"\w*"还是"\\w*"的问题这个表达式匹配由任意字母构成的序列。
将namespace字段的值写为"\w*",于是得到:
# 这是日志
[某个时间] [Render thread/ERROR]: Couldn't load pack metadata
<省略部分内容>:Invalid escape sequence at line 12 column 21 path $.filter.block[0].namespace(重点在这里)
[某个时间] [Render thread/WARN]: Missing metadata in pack file/test
也就是说必须转义反斜杠,把形如"\w*"的内容写成"\\w*"。(但其实这样写虽然能加载元数据,但是会重载资源失败,令人费解)
这里举一个例子。在pack.mcmeta中写入以下内容,以过滤continuity命名空间:
{
... ,
"filter": {
"block": [
{"namespace": "(continuity)"}
//该正则表达式直接过滤continuity命名空间,也就过滤了该模组自带的资源包
//不要学我在这里写注释
]
},
...
}这是加载包前和包后的对比,可以看出过滤效果:
未加载过滤资源包,可以看到连接纹理 | 加载资源包进行过滤,可以看到此时已经没有连接纹理 |
(这里没有任何对Continuity不敬的意思qwq,本人很喜欢Continuity)
path字段也是正则表达式,应该与namespace类似,大家可以自行探索其实是因为我不会了。
跨版本适配
这里的跨版本适配,指既支持1.21.9 25w31a及以后的版本,也支持这之前的版本的行为。
在1.21.9 25w31a中,Mojang对包支持版本区间的相关字段进行了改动,因此要跨版本的包里面的相关内容需要进行相应的修改。
pack字段中
拿支持1.21~1.21.11为例。这两者的格式版本号分别为34和75。
因为这个区间包括1.21.9 25w31a及以后和这之前的版本,因此相关的5个字段都需要填写。
需要注意,没有必要写成"supported_formats":[34,75],该字段在1.21.9 25w31a后弃用,可以写成[34,64](64即1.21.8,更改版本区间字段前的最后一个版本);因为类似的原因,pack_format需要在版本区间内。min_format和max_format需要正常填写。
实际写下来就是:
{
"pack": {
"description": "好看的介绍",
"pack_format": 64,
"supported_formats": [34,64],
"min_format": [34,0],
"max_format": 75
}
}另外还需要注意上文pack字段和叠加资源包相关内容中,支持版本区间字段下方的额外提示。
传送门






