Minecraft(我的世界)中文论坛

 找回密码
 注册(register)

!header_login!

只需一步,立刻登录

查看: 5608|回复: 21

[技巧教程] 【教程】[包教程/Pack Tutorial]资源包/行为包/附加包/SE等从入门到精通[紧跟最新版MC

[复制链接]
王咩咩 当前离线
积分
291
帖子
主题
精华
贡献
爱心
钻石
人气
下界之星
最后登录
1970-1-1
注册时间
2014-2-2
查看详细资料
 楼主| 发表于 2020-1-25 16:55:27 | 显示全部楼层 |阅读模式

您尚未登录,立即登录享受更好的浏览体验!

您需要 登录 才可以下载或查看,没有帐号?注册(register)

x
本帖最后由 王咩咩 于 2020-2-16 13:40 编辑

由于本人能力有限,难免会有疏漏,如有出错之处,还恳请大家不吝赐教,谢谢。
由于教程中不免会引用Wiki内容,故本教程采用CC BY-NC-SA 3.0协议发布,下文不再赘述
由于笔者从来没用过MCBBS发过贴所以不知道如何编辑地更好看一些,还希望大神指点
这里目前仅作存档用吧(这么难看也不适合看……),实时更新请关注文集:https://www.bilibili.com/read/readlist/rl121791
下文是直接拿word导入功能导入的……竟然把我的章节编号都自动给去掉了
正文:

一、清单文件
清单(Manifest)是MC识别你所制作的包(Pack)是哪一种类型的过程中最重要的也是第一个被验证(Validate)的文件,它的文件名必须为“manifest.JSON”,并位于你的包的顶级根目录上。在介绍该文件的具体内容及格式之前,笔者强烈建议在座的各位先学习JSON的语法。
1.  一个合适的文本编辑器
一般来说,在处理一些计算机语言的编写过程中,一个好的文本编辑器(Editor)或者IDE(集成开发环境)是尤其重要的,特别是语法高亮部分能够帮助初学者快速地理解和编写。如果你之后想学习Scripting Engine,那就更应该选择一个好的编辑器了,因为Scripting Engine(以后简称为SE)是用相对于JSON更加复杂的JavaScript语言(简称JS)编写的。(如果你之前写过ModPE,请无视刚才的这一段话)
推荐编辑器:
PC端:
Visual Studio Community或者 Visual Studio Code(十分好用)
Eclipse(十分好用)
Notepad++
记事本(千万别用!)
手机端:
920文本编辑器(较为传统了,不太好用了,不支持安卓高系统版本)
QuickEdit(十分好用)
MT管理器或ES文件浏览器自带的文本编辑器
备忘录(千万别用!)
2.  标准JSON语法
JSON(JavaScript Object Notation,JavaScript对象表示法)是一种轻量的数据交换格式。
别怕,JSON语法十分简单,如果你只是想学习普通的资源包和行为包制作,而不是去搞SE模组,那么只需要了解JSON就够了。
了解清单文件是进行开发的第一步,而在了解清单文件之前,学会JSON是必需的。JSON的语法可以参考:https://minecraft-zh.gamepedia.com/%E6%95%99%E7%A8%8B/NBT%E4%B8%8EJSONhttps://minecraft-zh.gamepedia.com/%E6%95%99%E7%A8%8B/%E5%88%B6%E4%BD%9C%E8%A1%8C%E4%B8%BA%E5%8C%85#JSON%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F
下面我们也会通过一个manifest.JSON文件的例子粗略学习一下JSON,若想了解具体更多的语法建议在CSDN或菜鸟教程等类似网站上搜索具体教程。
你也可以访问JSON官网来了解更多内容:https://www.json.org/json-zh.html,或查看RFC7159文件来查看JSON格式:http://www.rfc-editor.org/info/rfc7159
3.  manifest示例
下面这一段是官方的原版(Vanilla)资源包的示例清单文件:
//标准的JSON文件是不能添加注释的,但是MC中的可以
/*跨行注释
也是支持的*/
//JSON要求必须是以“{”开头以“}”结尾的,换句话说,整个JSON文件可以变相地看做是一个JS中的“对象(Object)”,但是语法要求稍更严格一些
{
    //我们一般都使用空格或制表符缩进代码使其更加易读
    //JSON中的键(Key)(名(Name),例如下面的“format_version”)必须以英文直双引号冠住,值(Value)如果是数字(Number,例如下面的“1”)就无须冠以引号,但是字符串(String,例如下面的“Example vanilla resource pack”)就必须冠以直引号,且引号必须为双引号
    "format_version": 1,
    //键和值组成一个键值对(Key-value Pair),也可以叫做一个字段(Field),值也可以为一整个对象,例如下面这一段,“header”的值为一个对象
    "header": {
        "description": "Example vanilla resource pack",
        "name": "Vanilla Resource Pack",
        "uuid": "66c6e9a8-3093-462a-9c36-dbb052165822",

        "version": [0, 0,1],

        "min_engine_version": [1, 2,6]

    },

    //值也可以是一个数组(Array),数组用“[”和“]”括起来,而非对象的“{”和“}”。数组是有序的,其内的值以这种方式排列:[1, 5,"abc", {}, [3, 4, true]]。可以看出,数组可以嵌套,数组中的元素(Element)可以是任意类型的值,例如数字、字符串、布尔值(Boolean,true和false,必须小写)、对象或另一个数组等,上述示例中“{}”是一个空对象。元素为对象的一个数组也可以看下面这一段,“modules”的值即是这样的一个数组

    "modules": [
        {
            "description": "Example vanilla resource pack",
            "type": "resources",
            "uuid": "743f6949-53be-44b6-b326-398005028819",

            "version": [0, 0,1]

        }
    ]
}
4.  清单文件标准格式
清单文件(Manifest File,manifest.JSON)是协助Minecraft识别你的包究竟是那种类型的包的重要助手。下面我们来看一下一个完整的manifest.JSON文件到底需要哪些元素。
UUID可以在这里获取:https://www.uuidgenerator.net/
语义化版本(Semantic Versioning)标准可以在这里查看:https://semver.org/lang/zh-CN/
{
  "format_version": 2, //Number,清单文件格式的版本,目前根据内部代码的升级,该版本号自1.13.0.9开始已由1更改为2,在官方更新版本之前请不要擅自更改
  "header": {
   "name": "Name", //String,该包的名字,将显示在游戏内
   "description": "MainDescription", //String,该包的简介,将显示在游戏内
   "uuid": "0ebeea65-76d6-4135-a5f9-44adc533e2db", //String,该包的UUID,格式为xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,其中x可以为任意数字或a-f的任意字母,不能和其他UUID相同
   "version": [ 0, 0, 1 ], //Array,该包的版本,格式为“语义化版本(Semver)”,即[Num1, Num2, Num3],分别为该包的主版本号、次版本号和修订号,这里代表0.0.1版本
   "min_engine_version": [ 1, 13, 0 ], //Array,可选,该包适配的最低MC版本,若MC低于该版本则不会工作,建议始终填写该包编写时的最新版本,除非你知道填写低版本不会出错
   "pack_scope": "global", //String,包的作用域,可以填入"global"或"world",缺省为"global"
   "directory_load": false, //Boolean,是否无视错误直接加载,true为是,缺省为false
   "load_before_game": false, //Boolean,是否优先于原版资源加载,true为是,缺省为false
   "lock_template_options": false, //Boolean,否锁定世界模板选项,true为是,缺省为false
   "platform_locked": false, //Boolean,是否锁定世界模板所创建的世界可用的平台,true为是,缺省为false
"population_control": false //Boolean,是否控制实体数,true为是,缺省为false
   //...
}, //Object,以上这部分是你的包的头(Header),这里是该包最主要的信息,所有类型的包的manifest都必须含有这个头
  "modules": [
   {
     "description": "Module1Description", //String,该模块的简介,不在游戏内显示
     "uuid": "c94c7c0c-f9a4-4eac-a196-6bb2768c0242", //String,该模块的UUID,不能和其他UUID相同
     "version": [ 0, 0, 1 ], //Array,该模块的版本,格式为“语义化版本(Semver)”
     "type": "resources" //该模块的类型,代表了该包拥有哪些功能,可以为“resources”“plugin”“client_data”“data”“interface”“mandatory”“world_template”“addon”“skin_pack”或“persona_piece”,各个分别的功能将在之后详细地描述
   }, //Object,模块一
   {
     "description": "Module2Description",
     "uuid": "45fa02fa-52fb-477a-ac29-dde17ea4b2df",
     "version": [ 0, 0, 1 ],
     "type": "interface"
   } //Object,模块二
   //...
], //Array,以上是该包具有的模块(Module),一个模块对应一个该包所具有的功能,可以有一个模块,也可以由多个模块,但不论有几个,这里都必须是一个数组的形式,而里面的每个模块分别以一个对象的形式存在,并且一个包至少要有一个模块
  "subpacks": [
   {
     "folder_name": "low", //String,该子包的文件夹名
     "name": "Low", //String,该子包显示在游戏中的名字
      "memory_tier": 1 //Number,该子包所需内存,1为最低,2为第二低,以此递推
   }, //Object,内存所需最低的子包
   {
     "folder_name": "medium",
     "name": "Medium",
     "memory_tier": 2
   }, //Object,内存所需第二低的子包
   {
     "folder_name": "high",
     "name": "High",
     "memory_tier": 3
   } //Object,内存所需第三低的子包
   //...
], //Array,可选,以上为该包的子包(Subpack),一个包可以没有子包(即没有该“subpacks”字段),也可以有若干个子包(在该数组内顺次排开),如果该包有子包,在游戏设置内会自动有一个点击进入选择子包的按钮和对应的界面
  "dependencies": [
   {
     "uuid": "50c11988-257e-4735-9d13-128f532ed509",
     "version": [ 0, 0, 1 ]
   } //Object,第一个依赖项
   //...
], //Array,可选,该包的依赖项,只有当该数组内所有包都加载时,该包才会加载。其中UUID和版本要完全对应才可。当你在游戏里将该包加入当前运行的包的列表时,该包如果有依赖项则它的依赖项也,会自动加入对应列表。
  "capabilities": [
   "experimental_custom_ui", //允许使用自定义HTML的UI
   "chemistry" //允许使用化学
   //...
], //Array,可选,该包额外的功能
  "metadata": {
   "authors": ["Author1", "Author2"], //Array,可选,作者姓名列表
   "license": "Pack'sLicense", //String,可选,包的证书
   "url": "This Pack's Offcial Website" //String,可选,包的或你的网站
  }//Object,可选,该包的作者信息
}
5.  清单各部分的详细介绍
看完刚才的标准清单文件格式,你应该已经对清单文件的大致结构有了初步的了解。如果你是第一次接触包的开发,那么对其中很多部分抱有疑惑是十分正常的事情。接下来,我们将通过更详细的介绍,为你依次对其中几个较为重要的部分进行解说。
1)  头的填写

上述文件中的"header"字段即是我们所说的头(Header)。Minecraft在载入你的资源包或行为包或其他种类的包时,会首先检测manifest.json文件,也就是前面所提到的清单文件。读取清单文件之后,Minecraft会紧接着检测整个包的结构,观测它是否有异常(Exception)。一般情况下,只有当包没有异常时,Minecraft才会开始读取包中其他实际的内容。在读取内容之前所做的这一系列步骤,在Minecraft中被称作包验证(PackValidation)。而读取我们的头,就是包验证中的第一步。

头中包含了所有你的包的基本信息,包括你的包的名称、简介、版本以及各种基本属性。其中"name""description""uuid""version"是必填字段,其他皆是选填字段。有些选填字段不填写并不意味着它们就不起作用,它们依旧会根据它们在源码中定义的默认值参与代码的执行。比如锁定模板选项的字段"lock_template_options",默认值是false,如果不填写,会默认按照false处理。

UUID(UniversallyUnique Identifier,通用唯一识别码)是你的包和其他包区分的唯一标识符,只有UUID和其他包不同,Minecraft才会认为你们是两个不同的包,否则,Minecraft只会使其中一个包发挥作用。所以"uuid"字段的值一定要是一个全新生成的UUID,每次填写这个字段,都要生成一个新的,以防和其他UUID重合。

2)  模块选取
从上面我们可以看到,模块(Module)的类型可以有很多种,他们根据源码可以分为两类。

第一类是资源包和行为包,目前它们分别为:“resources” “plugin” “client_data” “data” “interface”和“mandatory”;第二类是其他种类的包,目前分别为:“world_template” “addon” “skin_pack”和“persona_piece”。其中我们最常用的有下面几种,"resources"就是普通的资源包;"data"即是普通的行为包;如果一个行为包带有脚本引擎(SE),我们就应使用"client_data",否则,脚本不会执行。

3)  子包
为了使得一个资源包内有多个种类可以调节,比如,一个材质包有16x、32x、64x和128x的分辨率,或者,一个光影有低配、中配和高配三种配置,而不用更换资源包,Mojang在Minecraft里加入了子包(Subpack)的功能。
子包是通过清单文件和subpacks文件夹互相配合使用的。在清单文件里,如果你写入了"subpacks"字段,那么在包调整界面你加入此包时,就会显示如下扳手状按钮:
按下按钮后就会有如下调整界面 (以五边形材质包为例) :
而此时此刻如果你在subpacks文件夹里也同时有对应文件(依旧以五边形材质包为例):

那么游戏就会使用对应文件夹里的内容作为包的内容,也即例如在上图状态下,游戏会以<根目录>/subpacks/128x/文件夹下的所有文件作为当前的材质或资源。如果你有一定包开发基础或已经学习了部分后面内容,那么就会知道游戏此时会寻找<根目录>/subpacks/128x/contents.JSON,然后将此与<根目录>/contents.JSON合并(Merge),当做最终的文件内容输入游戏并应用这些资源。
使用子包并不是说所有文件都必须放在subpacks文件夹里了,事实上,你依旧可以像往常一样在根目录上进行你的制作,只不过,在根目录上的那些内容会被当做“缺省”,而如果根目录上的某文件与某子包中对应文件冲突,游戏会应用子包中的文件。
下面我们再来回顾一下清单文件中子包的写法。下面是一段节选:
  "subpacks": [
   {
     "folder_name": "low", //String,该子包的文件夹名
     "name": "Low", //String,该子包显示在游戏中的名字
     "memory_tier": 1 //Number,该子包所需内存,1为最低,2为第二低,以此递推
   }, //Object,内存所需最低的子包
   {
     "folder_name": "medium",
     "name": "Medium",
     "memory_tier": 2
   }, //Object,内存所需第二低的子包
   {
     "folder_name": "high",
     "name": "High",
     "memory_tier": 3
   } //Object,内存所需第三低的子包
   //...
  ]//Array,可选,以上为该包的子包(Subpack),一个包可以没有子包(即没有该“subpacks”字段),也可以有若干个子包(在该数组内顺次排开),如果该包有子包,在游戏设置内会自动有一个点击进入选择子包的按钮和对应的界面
我们可以看出,每个子包中都有三个字段。第一个是"folder_name",它的值应该填入该子包在包的subpacks文件夹中对应的文件夹名。例如,以五边形的128x分辨率为例,由于subpacks文件夹中128x分辨率的材质文件都在“128x”文件夹里,所以该字段的值就应该是"128x"。第二个"name"是该子包显示在游戏里的名字,也就是上述调整界面处显示的名字。根据上图,不难推断,五边形材质中这一字段的值也是"128x"。第三个是内存分配相关的字段"memory_tier",数字越小,代表该子包所需内存越少,当你的设备内存不足但是你在调整界面又选中了一个所需内存很大的子包时,Minecraft会给出警告,或者有时会直接隐藏那些子包的选项使其处于不可选中状态。
4)  包的依赖
"dependencies"字段填写了该包的依赖项(Dependency),该数组中的每一项都是该包所依赖的一个包。如果你的行为包需要对应的资源包才能正常工作,那么请在行为包的清单文件里的这一字段填写上你的资源包所对应的UUID和版本。
在上述情况下,当你在试图把这个行为包加入游,游戏会自动将该资源包也加入游戏。如果此时游戏找不到该资源包,那么就会给出错误提示。如果你在该行为包依旧起作用时试图卸载对应的资源包,游戏也会给出警告。
任何包都可以成为任何包的依赖项,比如,游戏的原版资源包和行为包事实上就是互相依赖的。
6.  清单作用
现在我们再来回顾一下清单文件:
1)清单文件是每个包都必须要有的文件;
2)清单告诉了游戏你的包叫什么名字,什么版本,有什么属性,是什么类型的包,包的结构以及是如何和别的包交互的;
3)游戏在侦测到你的包的存在后,首先会读取并验证你的清单文件,继而根据读取到的你的包的类型进行下一步操作,因此清单文件是一个包中最重要的部分。
没有了清单文件,整个包都将变得不可用。
二、包的结构
接下来我们介绍包的基本结构。不同类型的模块会使得包有不同的结构。介于篇幅有限,我们仅拿最常用的资源包(Resource Pack)和行为包(Behavior Pack)两种包结构作为介绍。
1.  资源包结构一览
下面是标准的完整资源包结构:
下面我们依次粗略地简介各个文件和文件夹的作用和功能:
1)  biomes_client.JSON(生物群系客户端定义)
这个文件定义了游戏中各个生物群系(Biome)的水体表面颜色、水体表面透明度、水体迷雾颜色和水中视距等渲染属性。对这部分我们之后会有详细的讲解。
2)  blocks.JSON(方块客户端定义)
这个文件定义了游戏中各个方块(Block)的渲染及声音属性,包括形状、材质和音效等。对这部分我们之后会有详细的讲解。
3)  bug_pack_icon.PNG(错误包图标)
当包加载出错时展示在包调整界面的图标。
4)  contents.JSON(内容文件)
这是包验证之后第二个载入的文件。如果该文件缺失,则游戏会调用原版资源包的这个文件作为替代。这个文件记录了包内所有的游戏之后将加载的文件,也就是你的包的内容(Content)。如果你的包不是完整的包,也就是说,例如,你的资源包内只有材质的相关文件,那么在内容文件里,请只填入与材质相关的文件,其他文件,例如音效文件,请不要填在内容文件里。
5)  items_offsets_client.JSON(物品偏移量客户端定义文件)
这个文件定义了使用虚拟现实设备时各个物品的渲染偏移量,包括平移、旋转和尺寸。对这部分我们之后会有详细的讲解。
6)  loading_messages.JSON(加载标语文件)
这是储存加载标语(Loading Message)的链接文件,其中加载标语就是每次进入世界时的那个“温馨提示”。加载标语内容本身并不是在这个文件中,他们位于各个本地化文本文件里,例如,汉语(简体)的加载标语位于<根目录>/texts/zh_CN.LANG文件里。这个文件只是告诉游戏,语言文件里的哪些字符串它是加载标语。
7)  manifest_publish.JSON(发布清单文件)
这是用于发布到Minecraft市场(Minecraft Marketplace,前Minecraft商店,Minecraft Store)的清单文件。如果你想成为Minecraft市场的创作者之一,请进入这个页面提交申请:https://creator.microsoft.com/en-us/minecraft。申请时国籍请勿填写中国,否则会跳转到网易的国服开发者申请页面,也就是这个页面:http://mc.163.com/developer_cn/
8)  manifest.JSON(清单文件)
这是本地的清单文件,也是我们平常使用的清单文件。
9)  pack_icon.PNG(包图标)
这是你的包展现在包调整界面的图标。
10) sounds.JSON(游戏声音定义文件)
这个是游戏声音(Sound)的链接文件,换句话说,这个文件告诉了游戏在游戏想播放特定声音时,它应该调用哪个文件。比如,当史蒂夫破坏方块时,游戏应该播放哪个音效,如果你修改了这个文件中的这一部分,把破坏的音效重链接到爬行者爆炸的声音,那么史蒂夫每破坏一个方块,都会听到一次爬行者爆炸的声音。对这部分我们之后会有详细的讲解。
11) splashes.JSON(闪烁标语文件)
这是储存闪烁标语(Splash)的文件,其中闪烁标语是你每次位于主界面上时,Minecraft图标右下角的“小黄字”。和加载标语不同,闪烁标语全部都存储在这个文件里,并且按照官方的规定,本地化时闪烁标语不在考虑范围之内。
12) ./animation_controllers/(动画控制器客户端定义文件)
这是储存生物的动画将在怎样的状态下进行怎样的改变的动画控制器(Animation Controller)的文件夹。对这部分我们之后会有详细的讲解。
13) ./animations/(动画客户端定义文件)
这是储存决定了生物的几何可以如何运动的动画(Animation)的文件夹。对这部分我们之后会有详细的讲解。
14) ./credits/(鸣谢文件)
这是存储员工列表(Credits)、终末之诗(End Poem)等文件的文件夹,官方给出的建议是不要修改该文件夹内的内容,因为修改该文件夹内的内容容易涉及到版权问题。
15) ./entity/(实体客户端定义文件)
这是储存实体(Entity)各项基本属性的定义的文件夹,是实体的总体定义文件。对这部分我们之后会有详细的讲解。
16) ./font/(字体文件)
这是储存Minecraft字体文件的文件夹,包括了适用于ASCII、Unicode等编码的不同字样。
17) ./items/(物品客户端定义文件)
这是储存物品(Item)的各项基本属性的定义的文件夹,包括物品的类型、渲染等。对这部分我们之后会有详细的讲解。
18) ./materials/(材质文件)
这是储存将由渲染器(Renderer)调用以表现物体对光的交互,供渲染器读取的数据集,包括贴图纹理、光照算法的材质(Material)的文件夹。对这部分我们之后会有详细的讲解。
19) ./models/(模型定义文件)
这是储存实体模型的几何(Geometry)及其基本图元(Primitive)的定义文件夹。
20) ./particles/(颗粒定义文件)
这是储存颗粒(Particle)效果定义的文件夹。对这部分我们之后会有详细的讲解。
21) ./render_controllers/(渲染控制器定义文件)
这是储存把生物的几何、材质和纹理连接起来的渲染控制器(Render Controller)的文件夹。
22) ./shaders/(着色器文件)
这是储存着色器(Shader)的文件夹。目前支持HLSL、GLSL和PSSL三种着色语言,分别对应三大种不同的平台的着色。对这部分我们之后会有详细的讲解。
23) ./sounds/(声音文件)
这是储存游戏内声音的文件夹。对这部分我们之后会有详细的讲解。
24) ./structures/(结构文件)
这是储存游戏内结构(Structure)的文件夹。
25) ./subpacks/(子包)
这是储存子包的文件夹。
26) ./texts/(本地化文本)
这是储存各国翻译文本的文件夹。
27) ./textures/(纹理文件)
这是储存纹理(Texture)图片的文件夹。对这部分我们之后会有详细的讲解。
28) ./ui/(UI定义文件)
这是储存UI(User Interface)的定义文件的文件夹。它们控制的是游戏内置的UI系统,而非我们前文曾提到的SE中的用户自定义UI。对这部分我们之后会有详细的讲解。
2.  行为包结构一览
下面是标准的行为包结构:
1)  contents.JSON(内容文件)
同前。
2)  manifest_publish.JSON(发布清单文件)
同前。
3)  manifest.JSON(清单文件)
同前。
4)  pack_icon.PNG(包图标)
同前。
5)  ./animation_controllers/(动画控制器服务端定义文件)
这里存储着服务端的动画控制器,用于表现其他除播放动画之外的与世界整体相关的性质,例如执行一个函数。
6)  ./attachables/(附着物定义文件)
这是储存附着在身上的装备(即附着物(Attachable))的定义的文件夹。连接了附着物的材质、纹理、几何、动画和渲染控制器。对这部分我们之后会有详细的讲解。
7)  ./behavior_trees/(行为树定义文件)
这是储存实体和玩家所有可能行为的组合的行为树(Behavior Tree)的文件夹。还在开发中。
8)  ./biomes/(生物群系服务端定义文件)
这是储存生物群系定义的文件夹。决定了世界中各个生物群系是如何生成的,以及具备什么特征。对这部分我们之后会有详细的讲解。
9)  ./cameras/(相机定义文件)
这是储存各个相机(Camera)的定义的文件夹。描述了各个相机的各属性值。注意,这里指的是代表游戏画面视角的相机,而非游戏中名为“相机”的物品或者方块。
10) ./entities/(实体服务端定义文件)
这是储存实体各个组件(Component)及事件(Event)等项目的文件夹。和脚本引擎有十分重要的联动。对这部分我们之后会有详细的讲解。
11) ./feature_rules/(地物规则定义文件)
这是储存地物(Feature)的生成规则定义的文件夹。对这部分我们之后会有详细的讲解。
12) ./features/(地物定义文件)
这是储存地物的定义文件的文件夹。在原版中主要控制了矿石和小型植物的生成。对这部分我们之后会有详细的讲解。
13) ./functions/(函数文件)
这里储存了用户自定义的函数(Function)文件。函数是一种命令(Command)批处理文件,同时允许有一定的逻辑。对这部分我们之后会有详细的讲解。
14) ./items/(物品服务端定义文件)
这里是储存着物品的服务端定义的文件夹。对这部分我们之后会有详细的讲解。
15) ./loot_tables/(战利品表定义文件)
这里是储存战利品表(Loot table)定义的文件夹。战利品表是一种可以用于在一个物品池按一定比例随机筛选出特定物品的表,常用于指定箱子打开时的内容、生物生成时的装备等。对这部分我们之后会有详细的讲解。
16) ./persona/(角色定义文件)
这是储存预设角色(Persona)的构件的定义文件的文件夹。
17) ./recipes/(配方定义文件)
这是储存物品配方(recipe)的定义的文件夹,包括工作台配方、熔炉配方等。对这部分我们之后会有详细的讲解。
18) ./scripts/(脚本引擎)
这是储存脚本引擎的文件夹。对这部分我们之后会有详细的讲解。
19) ./spawn_groups/(生成组定义文件)
这是储存生成组(Spawn group)的定义的文件夹,例如袭击(Raid)事件中掠夺者的群体生成。
20) ./spawn_rules/(生成规则定义文件)
这里是存储各个生物的生成规则的定义的文件夹。对这部分我们之后会有详细的讲解。
21) ./structures/(结构文件)
这里存储着所有的用户自定义结构文件。对这部分我们之后会有详细的讲解。
22) ./texts/(本地化文本)
同前。需要注意的是,如果你想在清单文件里用字符串来表示包的名字和简介等信息,那么你必须将字符串的本地化文本写在该行为包的这个文件夹内才可以实现。若写在其他包中,包括其他资源包中,即使这些包被激活,也无法实现该包的字符串在包调整界面中的本地化。
23) ./trading/(交易定义文件)
这里式储存着交易系统中所有的交易(Trade)信息的定义的文件夹。对这部分我们之后会有详细的讲解。
3.  内容文件
内容文件(contents.JSON)是记录该包内所有资源的文件,是一个JSON类型的文件。这是它在标准资源包的结构:
{
    "content": [
        {
            "path": "biomes_client.json"
        },
        {
            "path": "blocks.json"
        },
        {
            "path": "bug_pack_icon.png"
        },
        {
            "path": "items_offsets_client.json"
        },
        {
            "path": "loading_messages.json"
        },
        {
            "path": "manifest.json"
        },
        {
            "path": "pack_icon.png"
        },
        //...
        {
            "path": "ui/settings_sections/realms_world_section.json"
        },
        {
            "path": "ui/settings_sections/settings_common.json"
        },
        {
            "path": "ui/settings_sections/world_section.json"
        }
    ]
}
你可以看到,这个文件的是非常简单的,它只是单个文件的索引的堆积。但是,如果真想为你自己所有的文件去写这样一份内容文件,而你又没有一定的编程基础,那将会是一个比较困难的事情。因为你无法使用程序去做一个批处理。然而,事实上,实践证明,这个文件是可以缺失的。目前尚未发现任何由于缺失了该文件内的某个文件的索引而导致这个文件无法被游戏加载的状况。也就是说,目前游戏是默认加载包中所有的文件的,不管它是否被包含在contents.JSON文件内。
不过话又说回来,值得注意的是,游戏依旧会加载那些实际上并不存在但你却把它误写到了内容文件里的那些文件。如果这个文件还是游戏中的必要文件,那么游戏就可能因此而出错。比如,你保留了contents.JSON中所有"ui/..."文件夹里的字段,但是你在实际的目录里由于不想做UI把ui文件夹整个删除了。那么你在下一次启动游戏的时候,就可能会发现你的UI显示异常或者干脆不显示。
子包里的内容文件仅对该子包有效,并且会与根目录下的内容文件合并,继而继续与原版资源包或行为包中的内容文件合并(如果你在清单的头中开启了"load_before_game",则没有这最后一步)。
因此,虽然笔者建议按其标准认真建立内容文件,以防后日Mojang不再支持“该文件的缺失”,但是,在目前情况下,如果你认为你没有能力快速建立好内容文件,还是依旧可以不加入这个文件至你的包中的。
4.  基岩版创作者方针
这个方针是位于Wiki页面:https://minecraft.gamepedia.com/Tutorials/Bedrock_Edition_creator_guidelines中的一篇由Mojang官方上传的文档。笔者也曾将该文档翻译并上传至中文Wiki中。现在再把它放在这个教程里,作为本教程的一部分。这是因为这个文档里的注意事项正式笔者想对大家强调的。
由于部分概念的不理解,大家在阅读本文档时难免会有少许疑惑,这并不要紧。在今后的讲解中你将会慢慢接触到文档中做提及的各种概念,届时你可以重新回顾该文档,并加深你的理解。
下面是文档的正文:
基岩版创作者方针

此处提供的方针是为了使创作者得到为Minecraft创作内容时的较好体验的一种最佳操作。它将有助于确保作品可以工作,并且在应对游戏中的变化时具有高效性和弹性。
总方针
●从世界和包的目录中移除所有与内容无关的文件。
○不要在包中存放包,或存放Windows或Photoshop文件。它们中的任意一种都会在读取、导入或加载内容时导致出错。在发布之前从内容中移除任何未使用的资源。
○这能够保证在将内容缩减到最小的同时减少内容验证失败的可能性。
○此外,如果原版文件被修改,这样做对你的内容来说不会造成意外的更改。
●不同的平台有不同的路径长度限制。算上包或世界的路径,平台会计算导入到Minecraft里的目录长度。如果长度超出限制,包会导入失败并且会变成无效状态。正因如此,我们建议:
○保持路径长度为70字符或更少,即从包或世界模板的根目录到一个文件的最长路径长度应该只能有70字符长。
○路径中的每一部分(目录或文件名)必须小于60字符。否则,一些平台将无法识别这一部分。
○资源包或行为包的目录名应该小于10字符长。这样可以使创作者可以写更长的文件或子目录名。例如,bp_mw有如下目录:
?MyWorld/behavior_packs/bp_mw。
定义文件
●例如blocks.JSON、mobs.JSON、sound_definitions.JSON以及其他位置的定义文件包含了原版中所有元素的定义。请确保你的包只包含那些需要更改的元素和字段。这意味着:不要直接复制/粘贴所有原来的定义,然后只更改需要更改的那一段,而是仅需要保留文件中需要更改的那一段。游戏会自动将这些更改与原版的文件合并。
○如果需要更改的之外的某些部分也被留在了文件中,而原版的方块或生物在游戏版本更新时发生了更改,那么那一段就会造成内容里不必要的变更。
●以下文件不应该改写。它们还没有获得官方的支持,因此无法保证所做的更改会正常工作或在未来依旧能工作。
○credits/end.txt
○font/emoticons.json
○texts/language_names.json
○items_client.json
○items_offsets_client.json
○shaders目录里的任何文件
函数
●使用子目录来创建命名空间,以避免多个行为包的函数文件之间的冲突。如果一个函数的路径(以/functions/subdirectory开头)与另一个包一个函数的路径完全吻合,那么在包栈中靠近顶部的包会覆盖其他的包。
●为了减少你的函数在特定平台上无法工作的几率,请用使用小写字母且不留空格的方式来命名你的目录和函数文件,例如/functions/awesome_pack/level1_function.mcfuntion。
●请谨慎地使用递归。尽管递归是支持的,当递归很深的时候它依旧会导致一些性能问题。
●在你行为包清单文件的“min_engine_version”之后输入你当前开发所处的游戏版本,例如"min_engine_version": [1, 8, 0] 。
○这样你就可以控制使用哪个版本的命令来保证向后兼容性。
●如果你的命令方块只运行函数,那么修改他们就会变得简单很多。更重要的是,如果你发布了一个包函函数文件的新的行为包,那么使用那个行为包的世界也会在新包应用时立马得到更新。
●最后一个关键点是说明性的:当前的基岩版尚未支持条件分支(例如execute(if unless)),但是它可能会在未来加入到游戏中。
命令
●请避免每刻都执行命令。尤其重要的是不要每刻都执行大量的命令。
○尽量不要在每刻执行超过30条命令。
○如果需要频繁执行命令,可以考虑把它们放到一个时钟循环里,这样它们可以每5+刻执行一次。
○如上面所说,如果你设置了偏置时钟使得命令在不同的刻上执行,那么就可以平衡你的工作并获得更佳的性能。
○获知你内容的性能是否是由于命令过多而表现不佳的一个简单方法就是使用commandblocksenabled游戏规则来关闭所有命令方块的执行。
●请尽可能地不要使用长时命令(例如覆盖区域很大的/clone或/fill)。如果可以的话,请把它分开并在不同的刻执行。
●不要在目标选择器中使用物品的本地化名字,例如/testfor@e[name=beacon]。
○如果玩家来自不同语言区,那么物品的名字可能会改变而后命令将无法工作。
模型
●具有许多微小部件的模型在低端设备和某些GPU上性能可能会很差。请在细节与性能之间推敲出适当的平衡。
声音
●在流上只播放长时声音,例如背景音乐。
○可以获得游戏内更佳的性能。
○一些平台在同一时间只能打开一定数目的文件,在流上播放所有的声音可能会因内容过多而导致游戏崩溃。
●短时声音(例如音效)在内存上加载会有最佳性能。
●使用一些小技巧来缩小你的文件,例如从开头和结尾移出所有的静音部分
●有一个标识load_on_low_memory可以用于声音的定义里。这个标识缺省被设为false,这意味着如果此时计算机内存较低,它就不会再载入任何声音。如果对于某个特定的声音来说,它必须得到载入,那么就把这个标识设为true。请权衡利用这一特性。
UI
●所有UI的修改都是有风险的。如果原版的界面以某种形式被修改,那么使用这个界面的内容就有可能崩溃。UI系统是以一种有助于我们能灵活地通过JSON文件修改界面的方式设计的。任何对UI的JSON文件的更改(在一个自定义的资源包里)都会和原版的文件合并。如果合并过程不正确则游戏可能会进入一种不佳状态。
●重新绘制UI贴图,即修改他们所使用的材质,这样风险就会小很多,并且能做出一些更漂亮的元素。
●重新编辑元素的尺寸以及移动它们风险更大,但是在大多数情况下还是可行的。
●改变一个界面中的元素本身具有破坏性的高度风险。
修改UI示例
下面是一些示例,它们介绍了如何在不完全复制整个界面的前提下修改一个UI定义文件。下面以附魔台界面文件(enchanting_screen_pocket.json)的一部分为例。
示例1:减少变量
不要包含那些无需更改的变量。例如,如果"color""shadow"是要更改的,那么就不要把其他的变量复制/粘贴到这里。只需要声明那些需要替换的变量就可以完成简单的所需要的更改。
不佳的复制/粘贴法:
   "generic_label": {

      "type": "label",

      "color": "$pocket_title_text_color",

      "anchor_from": "center",

      "anchor_to": "center",

       "shadow": false
   },
更好的例子:
   "generic_label": {

      "color": "$pocket_title_text_color",

      "shadow": false

   },
示例2:继承
无需重新声明正在修改的控件所继承自的控件。仅声明正在修改的控件名即可。在下面的代码中,"common.button"就可以跳过不写:
不佳的例子:

  "enchanting_confirm_button@common.button": {

较好的例子:

  "enchanting_confirm_button": {

示例3:修改子控件
以同一个按钮为例,如果只需要修改该控件的子控件中的一些特定的变量,例如,default控件。仅修改一个控件的子控件请使用control_name/child_name语法。所以与之这样写:
   "enchanting_confirm_button@common.button": {

      "controls": [

       {

         "default@enchanting_pocket.confirm_default_control": {

            "type": "image",
            "texture": "textures/ui/button_borderless_light" //为default控件添加精美按钮材质

         }

       },

不如这样写:
   "enchanting_confirm_button/default": {

      "texture": "textures/ui/button_borderless_light" //为default控件添加精美按钮材质

  },

示例4:修改数组
这个示例将展示如何修改一个控件中的数组。例如:添加一个新的控件作为子控件或从一个控件的绑定中移除一个绑定。就该例来说,有一个叫"modifications"特殊的变量。对modifications数组里的每一条记录,可以指定一个特定的数组去修改、操作并输出结果。
"enchanting_book_panel"为例,如果需要在"controls"数组里添加一个控件,就可以添加一个modifications数组,数组中指定了"array_name": "controls""operation": "insert_front""value",其中最后一个中可以填入新的控件,新控件就会如同被放到了controls 数组里一样。下面的例子展示了上面所说的内容以及偏移量的更改。
"enchanting_book_panel": {

  "offset": [-4,1],

  "modifications": [

   {

     "array_name": "controls",

     "operation": "insert_front",

     "value": [

       "panel_outline@beacon_pocket.panel_outline":{

         "layer": 0

       }

     ]

   }

  ]
}
要从"player_level_label"子控件中移除"#player_level_color"绑定,可以进行如下操作:
"enchanting_book_panel/player_level_label": {

  "offset": [0,10],

  "layer": 3,
  "color": "$experience_text_color",
  "modifications": [

   {

     "array_name": "bindings",

     "operation": "remove",

     "where": {

       "binding_name": "#player_level_color"

     }

   }

  ]
}
世界
生物
●不要一次生成过多的实体。根据设备的不同,如果在同一时间有过多的实体更新,性能可能会很差。
红石
●只要有可能,就一定不要让红石元件在区块边界处交互。
○游戏是有能力处理大部分这种情况的,然而,的确有些例子表明当区块的加载和红石元件更新发生矛盾时,的确会引起一些元件失去它们的状态并破坏电路直到它们被重新放置。
○红石元件包括所有可以产生、传递或消耗红石信号的方块,例如:
?按钮
?命令方块
?比较器
?发射器
?漏斗
?拉杆
?观察者
?活塞
?铁轨:激活型、探测型和充能型
?红石线
?中继器
?以及其他
常加载区域
●不要过度使用常加载区域。
○这对低内存设备尤其重要。
●如果可以,在不使用常加载区域时请卸载它们。
○这可以使得设备回收一些内存,也可以为所需要的新的常加载区域腾出空间。
三、世界模板
下面我们讲解如何制作一个世界模板(World Template),在讲解具体的制作方法之前,我们先来了解一下基岩版的世界是如何构成的。
1.  基岩版世界结构
基岩版的世界和JAVA版类似,主体框架也是NBT结构。但是在各个方面又有许多不同。我们先来看一个世界的结构示例:
MyWorld
│  level.DAT
│  level.DAT_OLD
│  levelname.TXT
│  world_behavior_pack_history.JSON
│  world_behavior_packs.JSON
│  world_resource_pack_history.JSON
│  world_resource_packs.JSON
│  world_icon.JPEG
│  
├─behavior_packs
│  └─MyPack
├─db
│      000056.LOG
│      000058.LDB
│      000059.LDB
│      000060.LDB
│      CURRENT
│      MANIFEST-000050
│      LOCK
│      LOG.OLD
│      
└─resource_packs
    └─MyPack
这是一个刚刚创建的世界,并在创建的时候应用了资源包和行为包。我们今后称这样的一系列文件为一个存档(Level),而这个存档在游戏中具体生成的一切事物的集合为一个世界(World)。

现在我们关心存档的结构,所以下面我们将介绍基岩版的存档格式(LevelFormat)。

在每个存档中,level.DAT文件是必不可少的,我们称之为存档文件(Level File,level.DAT)。若缺失了存档文件或存档文件损坏,这个存档将无法被Minecraft读取。存档文件储存了这个存档的所有最基本的属性,具体内容后面我们会展开来讲。
level.DAT_OLD文件是为了兼容0.8.2之前的Minecraft而生成的。如果你的存档是从旧世界转换而来的,那么旧的level.DAT就会在转换过程中会被重命名为level.DAT_OLD。不过,在0.9.0之上的版本中,一个新建立的存档也会自带level.DAT_OLD文件,如果该文件被删除,游戏在下次打开这个存档时依旧会根据level.DAT生成一个新的level.DAT_OLD文件。
levelname.TXT文件就是一个简单的文本文件,它的唯一内容就是你的世界的名字。这个文件是随世界的生成一起生成的。当你在游戏界面编辑世界名字的时候,levelname.TXT会被更新(如果此时不存在会新建一个)。当你每次打开游戏,levelname.TXT也会被更新(不存在时同理)。然而,就算你更改这个文件的内容,你进入游戏看到的存档名也不会被改变(这是由于此时你看到的存档名是存档文件里存储的世界名)。这也就意味着,这个文件被删除,是不会在你正常游戏时产生影响的。
world_resource_packs.JSON和world_behavior_packs.JSON是这个世界当前正在应用的资源包和材质包,只包含它们清单头中的UUID和对应的版本号。world_resource_pack_history.JSON和world_behavior_pack_history.JSON则是所有在这个世界中应用过的资源包和行为包的更详细的信息,除了上述两项,它还包含了包的名字以及是否可以从Minecraft服务器中获取。最后一项是由"can_be_redownloaded"字段给定的,它是一个布尔值。如果你的包是从基岩版市场中获取的,那么这一个字段将是true。此时如果该包被删除,但是世界正在应用这个包,那么Minecraft在打开世界时便会自动从市场中下载该包的最新版本。否则将会提示有包缺失。所有曾应用于这个世界的包都会记录在这两个文件中,不论它们之后是否被取消或是删除。

./db/文件夹储存着所有的世界信息,包括主世界(theOverworld)、下界(the Nether,俗称地狱)和末路之地(the End,简称末地)的一切地形和生物。Mojang是用一种名为LevelDB(LevelDatabase)的文件格式来进行世界的NBT存储的。LevelDB是由Google的两名传奇工程师Jeff Dean和Sanjay Ghemawat开发并开源的一种键值(KV)非关系型数据库存储系统。Mojang在其基础上进行了修改,并引入了Zlib进行压缩,以适应Minecraft的读取和写入。db文件夹中的每一个LDB文件都是一个LevelDB数据库,存储着上百个区块(Chunk)的信息。游戏会自动将本地玩家(Local Player)所在的那个数据库的后缀变为.LOG。CURRENT的内容就是当前存档内的MANIFEST-<ID>文件的文件名(也就是“MANIFEST-<ID>”,不带引号)。而MANIFEST-<ID>是一个和level.DAT同类型的NBT文件。LOCK文件代表该世界是由锁定的(Locked)世界模板创建的,一般是空的,并不是每个世界都有这个文件。

存档使用了一段时间之后还可能在db文件夹中产生LOG文件或LOG.OLD文件,这是一个日志文件,是LevelDB的一部分。它很类似于其它程序的日志文件。它每行的格式为“YYYY/MM/DD-Hour/Minute/Second.StepName "Info"”。例如:

2019/11/17-11:39:30.855160c Recovering log #1894

2019/11/17-11:39:30.855160c Delete type=0 #1894

2019/11/17-11:39:30.855160c Delete type=3 #1892

2019/11/17-11:39:30.8713698 Compacting 143@0 + 5@1 files

2019/11/17-11:39:30.8893698 compacted to: files[ 143 5 35 0 0 0 0 ]


2020/01/22-00:11:17.7171bac Recovering log #106

2020/01/22-00:11:17.7211bac Delete type=0 #106

2020/01/22-00:11:17.7221bac Delete type=3 #104

如果需要,你可以在这里查看Mojang修改过的LevelDB:https://github.com/Mojang/leveldb-mcpe ,以及Tommaso所给出的构建参数:https://twitter.com/_tomcc/status/477950809427427328
(LevelDB中的level和前面提到的level关联不大。LevelDB中的level有“分层”之意,来自于level的本意“层级”;而level作为存档讲时,延伸于延伸意“关卡”。因此它们没有直接关联。)
2.  存档文件结构
我们详细看一下存档文件level.DAT的结构,这或许对地图开发者有一定帮助。如果你对这部分不感兴趣,你可以跳过这一节。
在阅读这一节之前,笔者强烈建议先了解NBT的格式:https://minecraft-zh.gamepedia.com/NBT%E6%A0%BC%E5%BC%8F ,后面将直接使用NBT相应的一些术语而不做任何解释。
下面是存档文件的结构:

abilities://Compound,初始玩家的能力(Ability),即新建立的玩家将拷贝该字段作为其能力,现有的玩家会使用其相关LevelDB键中的数据,不会使用该数据

lastOpenedWithVersion://List,该世界上次保存(Save)的游戏版本,例如[1, 14, 1, 5,0]或[1, 12, 5, 0, 1]

MinimumCompatibleClientVersion://List,该世界最低能在哪一个版本中打开,例如[1, 14, 0, 9, 0]或[1, 12, 5, 0, 1]

baseGameVersion://String,意义不明,观测值总为"*",至少1.12之前没有该字段

bonusChestEnabled://Byte,是否开启奖励箱(Bonus Chest),1为是

bonusChestSpawned://Byte,是否在出生点(Birth Point)生成奖励箱,1为是

CenterMapsToOrigin://Byte,是否将新创建地图(Map)的中心对齐到玩家所在处,1为是,否则将对齐区块边界

commandblockoutput://Byte,是否在聊天栏中向管理员输出命令方块(Command Block)执行信息,1为是

commandblocksenabled://Byte,是否在游戏中启用命令方块,1为是,否则命令方块将无法激活(Activate)

commandsEnabled://Byte,是否开启命令,1为是

ConfirmedPlatformLockedContent://Byte,意义不明

currentTick://Long,当前世界创建以来过去的总刻数,单位:游戏刻(Gametick)

Difficulty://Int,存档难度(Difficulty),0为和平(Peace),1为简单(Simple),2为普通(Normal),3为困难(Hard)

dodaylightcycle://Byte,是否开启日夜交替和月相变化,1为是

doentitiydrops://Byte,是否开启非生物(Non-mob)实体掉落物品,1为是

dofiretick://Byte,是否开启火焰蔓延和自动熄灭,1为是

doimmediaterespawn://Byte,是否在玩家死亡时立即重生,1为是,否则将显示死亡信息界面(“你失败了”)

doinsomnia://Byte,是否开启失眠模式(Insomnia Mode),1为是,否则幻翼(Phantom)不会生成

domobloot://Byte,是否开启生物(Mob)掉落物品,1为是

domobspawning://Byte,是否开启生物自然生成,1为是,不影响刷怪箱(Spawner)

dotiledrops://Byte,是否开启方块掉落,1为是

doweathercycle://Byte,是否开启天气(Weather)变化,1为是

drowningdamage://Byte,是否开启溺水(Drown)伤害,1为是

educationFeaturesEnabled://Byte,是否开启教育版(Education Edition)特性,1为是

eduOffer://Int,该存档是否是从教育版保存的,0为否,否则基岩版将无法打开这个存档,且游戏会给出相应提示

experimentalgameplay://Byte,是否开启实验性玩法(Experimental Gameplay),1为是

falldamage://Byte,是否开启跌落(Fall)伤害,1为是

firedamage://Byte,是否开启火焰伤害,1为是

FlatWorldLayers://String,平坦(Flat)世界的层(Layer),默认为"null?",有效格式是一个字符串型的对象,例如'{"biome_id":1,"block_layers":[{"block_data":0,"block_name":"minecraft:invisibleBedrock","count":255}],"encoding_version":4,"structure_options":null}'(不带单引号)是一个被隐形基岩(Invisible Bedrock)填满了的世界,生物群系为平原(Plain),该字段只在没有任何地形(Terrain)被生成前有效

ForceGameType://Byte,是否锁定游戏模式(Game Mode),1为是

functioncommandlimit://Int,单次函数执行中命令的最大数量限制,默认是10000

GameType://Int,游戏模式,0为生存(Survival)模式,1为创造(Creative)模式,2为冒险(Adventure)模式

Generator://Int,世界类型(World Type),0为旧(Old)世界,1为无限(Infinite)世界,2为平坦(Flat)世界

hasBeenLoadedInCreative://Byte,是否存在一名玩家曾在创造模式中加载(Load)过该世界,1为是,该项每次打开世界都会被更新

hasLockedBehaviorPack://Byte,是否锁定了行为包,1为是

hasLockedResourcePack://Byte,是否锁定了资源包,1为是

immutableWorld://Byte,是否开启不变世界,1为是,此时任何不具备世界建造者(World Builder)权限的玩家将无法破坏(Destroy)或放置(Set)方块,除非它们位于允许方块(Allow Block)的范围内

InventoryVersion://String,物品栏(Inventory)版本,通常为你保存该世界时的游戏的前三位版本号,例如"1.14.1"

isFromLockedTemplate://Byte,该世界是否是从锁定的世界模板创建的,1为是

isFromWorldTemplate://Byte,该世界是否是从世界模板创建的,1为是

isWorldTemplateOptionLocked://Byte,该世界的设定是否被世界模板锁定,1为是

keepinventory://Byte,是否开启死亡不掉落,1为是

LANBroadcast://Byte,是否允许该世界被向局域网广播(Broadcast),1为是

LANBroadcastIntent://Byte,是否向局域网广播该世界,1为是

LastPlayed://Long,存储上一次玩家退出时的Unix时间戳,单位:秒

LevelName://String,存档名称

lightningLevel://Float,雷电等级,范围[0, 1]

lightningTime://Int,距离下一次进入雷电天气还剩的刻数,单位:游戏刻

LimitedWorldOriginX://Int,有限世界生成的初始X坐标

LimitedWorldOriginY://Int,有限世界生成的初始Y坐标

LimitedWorldOriginZ://Int,有限世界生成的初始Z坐标

maxcommandchainlength://Int,连锁型命令方块的最大连锁数量,默认为65535

mobgriefing://Byte,是否开启实体破坏,1为是,否则苦力怕、僵尸、末影人、恶魂、凋灵、末影龙、兔子、羊、村民和雪傀儡将无法放置、修改或破坏方块,生物将不能捡拾物品,僵尸将无法寻找海龟蛋,村民将无法自然繁殖。

MultiplayerGame://Byte,是否允许该世界支持多人游戏,1为是

MultiplayerGameIntent://Byte,是否开启局域网和Xbox多人游戏,1为是

naturalregeneration: //Byte,是否开启生命自然恢复,1为是,否则将无法通过由足够的饥饿值来回复生命值

NetherScale://Int,主世界相对于下界的比例,默认为8

NetworkVersion://Int,网络版本,基岩版目前是389,教育版目前是361

Platform://Int,该存档是在何种平台(Platform)上保存的,观测值总为2

PlatformBroadcastIntent://Int,在平台间广播游戏的范围,观测值总为3

prid://String,意义不明,观测值总为""

pvp://Byte,是否开启友军伤害(PVP,Player versus Player),1为是

rainLevel://Float,雨雪等级,范围[0, 1]

rainTime://Int,距离下一次进入雨雪天气还剩的刻数,单位:游戏刻

RandomSeed://Long,存档的种子(Seed)

randomtickspeed://Int,随机刻(Random Tick)速度,即每游戏刻每区段(Section)产生的随机方块刻(Blocktick)数量,默认为1,单位:方块刻/(游戏刻·区段)

requiresCopiedPackRemovalCheck://Byte,意义不明

sendcommandfeedback://Byte,是否向命令执行者输出命令执行信息,1为是

serverChunkTickRange://Int,作为服务端时该存档内区块更新的范围,单位:区块

showcoordinates://Byte,是否显示实时坐标(Coordinate),1为是

showdeathmessages: //Byte,是否显示死亡信息,1为是

showtags://Byte,是否显示生物名字标签,1为是

spawnMobs://Byte,是否生成生物,1为是,观测该字段不起作用

spawnradius://Int,没有重生点(Spawn Point)或重生点的床被破坏的玩家出生(bear)或重生(respawn)时距离出生点的距离,默认为5

SpawnV1Villagers://Byte,是否生成旧版村民(Villager),1为是

SpawnX://Int,出生点的X坐标

SpawnY://Int,出生点的Y坐标

SpawnZ: //Int,出生点的Z坐标
startWithMapEnabled: //Byte,是否开启初始地图,1为是
StorageVersion: //Int,基岩版存储工具的版本,当前为8

texturePacksRequired://Byte,是否需要材质包,1为是

Time://Long,当前世界的时间(Time),单位:游戏刻

tntexplodes://Byte,是否开启TNT爆炸,1为是

useMsaGamertagsOnly://Byte,是否仅在游戏中使用微软账号(Microsoft Account,MSA)的玩家代号,1为是,从本地(Local)创建的世界默认为0,从领域(Realm)创建的世界默认为1

worldStartCount://Long,意义不明

WorldTemplateId://String,世界模板ID,通常不存在,当该世界是从世界模板创建时,为该世界模板清单头中的UUID

XBLBroadcastIntent://Int,Xbox Live广播(Xbox Live Broadcast,XBLB)范围,1为仅邀请,2为仅好友,3为好友的好友

以下是教育版存档独占的一些NBT标签:

abilities.mute://Byte,玩家是否被禁言(Mute),1为是,此时玩家无法在聊天栏中发送消息

abilities.worldbuilder://Byte,玩家是否为世界创造者,1为是

allowdestructiveobjects://Byte,是否允许毁灭性物品存在,如TNT等,1为是

allowmobs://Byte,是否允许生物存在,1为是

codebuilder: //Byte,是否开启代码生成器(Code Builder),1为是,此时可以按C键以打开代码生成器

EducationOid://String,教育版某ID,意义不明,观测值总为一个Version 4 UUID

EducationProductId://String,教育版某ID,意义不明,观测值总为一个Version 4 UUID

globalmute://Byte,是否开启全员禁言,1为是

isSingleUseWorld://Byte,是否为单学生游戏,1为是,否则将可以开启多学生模式

limitedWorldDepth://Int,限制世界深度,意义不明

limitedWorldWidth://Int,限制世界宽度,意义不明

3.  LevelDB结构
由于存档文件是一个存档中最基础的文件,故而笔者单独进行介绍。存档中储存世界信息的其他文件都位于LevelDB文件内,由于其过于复杂,下面只进行简要说明。
LevelDB在最新版本中是分区块及区块下的子区块(Subchunk,即PC中通常所说的区段,Section)存储的。子区块亦即区段是Minecraft存储格式及运行格式的一种。我们先来回顾一下PC中是如何存储和运行世界的。

区域文件格式(Region File Format)为在Minecraft Beta 1.3中为存储区块所引入的一种文件格式,它取代了之前的Alpha存档格式(AlphaLevel Format),其中每32×32个区块被编为一组被存储进一个独立的区域文件(RegionFile,*.MCR),称为一个区域(Region)。而每个区块中又有16个自下而上的不同区段。所以每个区段是一个16×16×16个方块的立方体。区段自下而上的序号(Index)为0至15。区域文件格式在Minecraft 1.2.1中被砧文件格式(AnvilFile Format,*.MCA)所取代,并沿用至今。其中区段在方块刻的更新中起重要作用。区域、区块和区段的概念至今一直在使用。

而基岩版中,我们了解到,方块刻的更新也是以区段为单位的。但是,由于Mojang在LevelDB中使用了另一个术语“子区块”来代替“区段”,所以下文我们使用“子区块”来表述这一概念。
在LDB文件中,每个区块是由一系列键来描述的,这些键共同描述该区块,是并列关系。每个键的组成包括五部分,与该键具体储存的数据一起合称作一条记录(Record),每一个部分是一个字段:
1) 第一个带符号32位整数,存储X区块坐标(ChunkCoordinate)
2) 第二个带符号32位整数,存储Z区块坐标
3) 第三个带符号32位整数,存储该区块的维度,0为主世界,1为下界,2为末路之地,可选,缺省为主世界
4) 第一个1字节标签,存储该键所代表的记录的类型,见下表
5) 第二个1字节标签,存储子区块的序号,仅该记录为“SubChunkPrefix”时有效,其余时不存在该字段
区块坐标和世界坐标所采取的坐标轴方向一致,世界坐标的细度为区块坐标的16倍。即
记录类型表如下:
Dec  Hex ASCII   名字    描述
45   2D  -   Data2D  生物群系和海拔
46   2E  .   Data2DLegacy    旧版生物群系和海拔
47   2F  /   SubChunkPrefix  一个16×16×16子区块的地形
48   30  0   LegacyTerrain   旧版整个区块的地形
49   31  1   BlockEntity 方块实体数据
50   32  2   Entity  实体数据
51   33  3   PendingTicks    挂起刻数据
52   34  4   BlockExtraData  方块额外数据
53   35  5   BiomeState  生物群系状态
54   36  6   FinalizedState  子区块最终状态
55   37  7   观测到  意义不明
56   38  8   观测到  意义不明
57   39  9   观测到  意义不明
118  76  v   Version 版本
上述五部分是原本是以字节数组的格式储存在LevelDB文件内的,但是为了更加清楚地展现,我们下面全部采用与其对应的16进制(Hex)字符串的形式来描述键名。这五部分是以从高至低的顺序排列的,而每一个整数自身又是由小端序(Little-endian,低字节放在低地址)的方式排列的。
用户midnightfriddie在GitHub上有一个开源项目McpeTool:https://github.com/midnightfreddie/McpeTool 。该工具可以查看存档文件以及LevelDB文件内的各种详细信息,包括上面提到的一切。我们采用McpeTool文档内给出的一个例子来进行更详细的讲解。
我们考虑世界坐标413, 54, 105所在的子区块的地形数据的键名。我们先换算成区块坐标:
l  X = 413 / 16 = 25 或 0x19 (小端序带符号32位整数字节数组[0x19,0, 0, 0],用字符串表示为19000000,符号位在最高位(即最右))余 13
l  Z = 54 / 16 = 3([0x3, 0, 0, 0],也即03000000) 余 6
我们从上面的表格中知道地形对应的前缀是2F,那么19000000030000002f就应该是代表该区块该记录类型。但是我们又知道当类型为2F时,应该还有一个子区块编号,我们计算这个8位无符号的子区块编号:
l  Y = 105 / 16 = 6([0x06],也即06) 余 9
故该键的完整名应为9000000030000002f06。
由于Minecraft是按照从小编号至大编号检索世界的,所以这要求只要某一个子区块存在,编号比它小的子区块必须存在。故而我们知道该LevelDB中必也存在9000000030000002f00至9000000030000002f05的键,但是更高的键的存在性仅依据此依旧无法判断。
如果该子区块存在于下界,那么该键名应该为900000003000000010000002f06,如果是末路之地,则应为900000003000000020000002f06。
上述很多内容涉及到区块的运作方式,目前不再进行赘述。一些记录的类型被观测到(如0x37、0x38、0x39),但目前无法确认是何种记录。使用MCC Tool Chest等可视化工具可以编辑到所有的数据,并且这些工具内对各类数据已经做了更科学的重新分类,所以如果你不是专门研究这一方面的人员,大可不必再继续深究。“.”和“0”是Minecraft在0.12.3之前未引入子区块前使用的值,目前已不再使用。
我们在LevelDB中仍能找到一些和区块无关的键,它们的键名是直接以字符串的形式存储的,不过为了与上述键名对应,我们仍也以对应的16进制描述他们:
1) ~local_player(7e6c6f63616c5f706c61796572)
本地玩家的NBT标签。只有你在本地游戏时才会使用这个标签,存储本地玩家的所有状态与能力、物品栏和末影箱等。其中很多字段都可以顾名思义,故不在本节中具体描述。
2) player_<MSA-UUID>(706c617965725f<MSA-UUID-Hex>)
在线玩家的NBT标签之一,存储了玩家的微软账户UUID、自签名UUID和服务器UUID,三个UUID均为Version 4 UUID。键名是玩家的微软账户UUID。
3) player_server_<Server-UUID>(706c617965725f7365727665725f<Server-UUID-Hex>)
在线玩家的NBT标签之二,和本地玩家的格式完全相同。键名是玩家的服务器UUID。
4) AutonomousEntities(4175746f6e6f6d6f7573456e746974696573)
独立实体数据。
5) BiomeData(42696f6d6544617461)
生物群系数据,记录生物群系。
6) Nether(4e6574686572)
下界数据。
7) Overworld(4f766572776f726c64)
主世界数据。
8) TheEnd(546865456e64)
末地数据,其中包括Boss战的状态信息。
9) portals(706f7274616c73)
所有下届传送门(Nether Portal)的记录信息。
10)scoreboard(73636f7265626f617264)
计分板(Scoreboard)信息。
11)mobevents(6d6f626576656e7473)

实体事件(MobEvent)数据,控制各实体事件是否开启。目前实体事件只有两个,其一是灾厄巡逻队(Patrol)生成,另一个是流浪商人(WanderingTrader)生成。

12)schedulerWT(7363686564756c65725754)
流浪商人生成数据,控制流浪商人的具体生成模块。
13)map_<Map-ID>( 6d61705f<Map-ID-Hex>)
地图数据。键名是地图的ID,观测值多为10位、11位和12位10进制整数,正负皆有,复数以“-”开头。
14)VILLAGE_<Village-UUID>_DWELLERS(56494c4c4147455f<Village-UUID-Hex>5f4457454c4c455253)
新版村庄(Village)居民数据,记录该村庄中都有哪些村民。键名是村庄UUID,为一个Version 4 UUID。
15)VILLAGE_<Village-UUID>_INFO(56494c4c4147455f<Village-UUID-Hex>5f494e464f)
新版村庄信息数据,记录该村庄基本信息。键名是村庄UUID。
16)VILLAGE_<Village-UUID>_PLAYERS(56494c4c4147455f<Village-UUID-Hex>5f504c4159455253)
新版村庄玩家数据,记录该村庄与那些玩家交互过。键名是村庄UUID。
17)VILLAGE_<Village-UUID>_POI(56494c4c4147455f<Village-UUID-Hex>5f504f49)

新版村庄兴趣点(Point ofInterest,POI)数据,记录该村庄的兴趣点。键名是村庄UUID。

18)tickingarea_<TA-UUID>(7469636b696e67617265615f<TA-UUID-Hex>)
常加载区域(Ticking Area)数据,记录该常加载区域的各种信息。
19)mVillages(6d56696c6c61676573)(已过期!)
在1.11之前,旧版村庄均使用该键存储。
20)game_flatworldlayers(67616d655f666c6174776f726c646c6179657273)(已过期!)
在1.5之前,相当长一段时间内平坦世界的层以该键存储在LevelDB文件内,它的值与0.10之前在options.TXT中时的值的格式完全相同;目前已经被移动到level.DAT中。
4.  制作世界模板
在本章的最后一节,我们来讲解本章的核心问题,也就是制作一个世界模板。
笔者认为大家已经熟知了一些基本的从资源管理器中操作存档、包以及更改Minecraft设定的相关知识,和com.mojang文件夹的结构。如若不然,请大家参考官方Wiki关于com.mojang的部分:https://minecraft.gamepedia.com/Com.mojang
假设现在你有一个已经制作完毕的存档,想把它做成一个世界模板当做一个新地图进行发布。
首先你需要确保该世界所应用的所有资源包和行为包都被包含到了这个世界目录下的resource_packs和behavior_packs目录下。由于Minecraft的一些机制,部分比较大的包和development_前缀的文件夹内的包不会在应用到世界时被拷贝至世界内。你需要手动将它们拷贝到世界内。
现在你拥有了一个“完整的”世界存档,不妨设存储该存档的文件夹名字为MyWorld。现在你需要将MyWorld文件夹从minecraftWorlds文件夹内(或其原本所在的文件夹内)拷贝到world_templates文件夹内,并在MyWorld文件夹内(即与存档文件level.DAT同级目录内)创建一个清单文件manifest.JSON。这个清单文件的结构就如同第一章所述,唯一的不同是模块处的类型应填写为"world_template"。此时你打开游戏,便可以看到你已经拥有了一个世界模板。并且该模板已经可以正常运作了。至此,一个最普通的世界模板便制作成功。
如果你想对该世界模板中清单文件头中的名字和简介使用本地化文本,你也可以在这个同级目录下建立texts文件夹以及对应的.LANG文件,具体就不再赘述。
.ZIP格式的世界模板也是可行的。你对你刚制作好的世界模板MyWorld进行压缩,压缩至ZIP格式,并放入world_templates文件夹中,并将原来的MyWorld文件夹移至别处,你便可以使用压缩成一个单独档案的世界模板了。游戏会在每次打开时将该压缩档案解压到内存中,所以建议不要将体积非常大的世界模板做成这样,否则将大幅拖慢游戏打开速度。
将上述压缩包的后缀名改为.MCTEMPLATE,便将其制作成为一个具备导入功能的世界模板。你在发布世界模板时便可以使用这个文件进行发布。双击(PC上)或选择打开方式为Minecraft(各种设备皆可)便可以打开Minecraft并自动开始世界模板导入。导入完成后便可以正常使用了。该格式文件也支持直接放入world_templates文件夹内使用,因为它本身就是一个ZIP文件。
我们可以通过修改清单的头来实现一些额外的功能,具体可以参考第一章第4节。

评分

参与人数 2人气 +3 收起 理由
小涵呀 + 1 MCBBS有你更精彩~
innc + 2 MCBBS有你更精彩~

查看全部评分

王咩咩 当前离线
积分
291
帖子
主题
精华
贡献
爱心
钻石
人气
下界之星
最后登录
1970-1-1
注册时间
2014-2-2
查看详细资料
 楼主| 发表于 2020-1-25 16:58:36 | 显示全部楼层
这是预估的目录第一章?清单文件 DONE
第二章?包结构 DONE
第三章?世界模板 Almost DONE
第四章?资源包初步
第五章?资源包-材质包
第六章?资源包-光影
第七章?资源包-UI
第八章?资源包-音效&音乐
第九章?行为包初步
第十章?行为包-函数
第十一章?行为包-实体
第十二章?行为包-自定义物品和生物群系
第十三章?行为包-颗粒&动画
第十四章?行为包-脚本引擎
第十五章?行为包-自定义UI
第十六章?皮肤包
第十七章?附加包&捆绑包制作


在B站每更新一段时间会来这边更新一次,有大神教我排版MCBBS吗QAQ
回复

使用道具 举报

蓝莓的世界 当前离线
积分
137
帖子
主题
精华
贡献
爱心
钻石
人气
下界之星
最后登录
1970-1-1
注册时间
2015-1-2
查看详细资料
发表于 2020-2-1 22:44:31 | 显示全部楼层
涨知识了,才知道命令方块是红石元件
这本数学书真棒(
回复

使用道具 举报

一休哥 当前离线
积分
36
帖子
主题
精华
贡献
爱心
钻石
人气
下界之星
最后登录
1970-1-1
注册时间
2014-2-12
查看详细资料
发表于 2020-2-9 22:38:50 | 显示全部楼层
学到了谢谢
回复

使用道具 举报

_God 当前离线
积分
30
帖子
主题
精华
贡献
爱心
钻石
人气
下界之星
最后登录
1970-1-1
注册时间
2020-2-10
查看详细资料
发表于 2020-2-10 08:22:44 来自手机 | 显示全部楼层
好活 不觉明厉凑满十字
回复

使用道具 举报

T.C.T_093 当前离线
积分
108
帖子
主题
精华
贡献
爱心
钻石
人气
下界之星
最后登录
1970-1-1
注册时间
2014-11-21
查看详细资料
发表于 2020-2-13 09:00:03 | 显示全部楼层
学到了,谢谢楼主
回复

使用道具 举报

王咩咩 当前离线
积分
291
帖子
主题
精华
贡献
爱心
钻石
人气
下界之星
最后登录
1970-1-1
注册时间
2014-2-2
查看详细资料
 楼主| 发表于 2020-2-18 23:00:08 来自手机 | 显示全部楼层
蓝莓的世界 发表于 2020-2-1 22:44
涨知识了,才知道命令方块是红石元件
这本数学书真棒(

Emmm那一段是Mojang写得,原文就是红石元件,我莫得改…
回复

使用道具 举报

theredcap 当前离线
积分
124
帖子
主题
精华
贡献
爱心
钻石
人气
下界之星
最后登录
1970-1-1
注册时间
2020-2-26
查看详细资料
发表于 2020-3-4 16:17:08 | 显示全部楼层
好东西收藏了
回复

使用道具 举报

Morison29 当前离线
积分
60
帖子
主题
精华
贡献
爱心
钻石
人气
下界之星
最后登录
1970-1-1
注册时间
2020-2-21
查看详细资料
发表于 2020-3-16 17:54:55 | 显示全部楼层
好强的干货,先马一个!
回复

使用道具 举报

雪乐遥 当前离线
积分
171
帖子
主题
精华
贡献
爱心
钻石
人气
下界之星
最后登录
1970-1-1
注册时间
2020-2-7
查看详细资料
发表于 2020-3-16 20:25:01 来自手机 | 显示全部楼层
座等我想要学习的第8章
回复

使用道具 举报

SpawnGames 当前离线
积分
107
帖子
主题
精华
贡献
爱心
钻石
人气
下界之星
最后登录
1970-1-1
注册时间
2019-9-21
查看详细资料
发表于 2020-3-25 10:24:06 来自手机 | 显示全部楼层
感谢大佬的教程~收藏了
回复

使用道具 举报

persielin 当前离线
积分
128
帖子
主题
精华
贡献
爱心
钻石
人气
下界之星
最后登录
1970-1-1
注册时间
2020-3-5
查看详细资料
发表于 2020-4-3 13:00:33 | 显示全部楼层
支持!非常需要此方面的资料。感谢楼主分享.希望楼主加油
回复

使用道具 举报

Quickly_boy 当前离线
积分
36
帖子
主题
精华
贡献
爱心
钻石
人气
下界之星
最后登录
1970-1-1
注册时间
2020-4-1
查看详细资料
发表于 2020-4-5 22:50:15 来自手机 | 显示全部楼层
知识增加了!
回复

使用道具 举报

pipoa 当前离线
积分
882
帖子
主题
精华
贡献
爱心
钻石
人气
下界之星
最后登录
1970-1-1
注册时间
2019-12-8
查看详细资料
头像被屏蔽
发表于 2020-4-8 22:26:30 | 显示全部楼层
排版方面需要改进,可以增加图文方式方便理解
回复

使用道具 举报

pipoa 当前离线
积分
882
帖子
主题
精华
贡献
爱心
钻石
人气
下界之星
最后登录
1970-1-1
注册时间
2019-12-8
查看详细资料
头像被屏蔽
发表于 2020-4-8 22:26:57 | 显示全部楼层
看的头晕眼花
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册(register)

本版积分规则

Archiver|小黑屋|Mcbbs.net ( 京ICP备15023768号-1 ) | 京公网安备 11010502037624号 | 手机版

GMT+8, 2021-9-29 07:06 , Processed in 0.080729 second(s), Total 39, Slave 31 queries, Release: Build.2021.09.22 1647, Gzip On, Redis On.

"Minecraft"以及"我的世界"为Mojang Synergies AB的商标 本站与Mojang以及微软公司没有从属关系

© 2010-2020 我的世界中文论坛 版权所有 本站原创图文内容版权属于原创作者,未经许可不得转载

快速回复 返回顶部 返回列表