forked from zhangshenxing/VanillaModTutorial
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
12064 lines (11492 loc) · 592 KB
/
index.html
File metadata and controls
12064 lines (11492 loc) · 592 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!doctype html>
<html lang="zh-Hans-CN">
<head>
<meta charset="utf-8" />
<title>Minecraft 原版模组入门教程</title>
<meta name='author' content='ruhuasiyu@mcbbs' />
<meta name='keywords' content='minecraft, 原版模组, vanilla mod, datapacks' />
<meta name='description' content='Minecraft 原版模组入门教程' />
<meta name='revised' content='ruhuasiyu@mcbbs' />
<base href="" />
<link rel="shortcut icon" href="https://zhangshenxing.gitee.io/favicon.ico" />
<link rel="stylesheet" href="items/style.css" />
<script>
function hidecomment(thiselement){
var classElements = document.getElementsByClassName('comment');
for (var i=0; i<classElements.length; i++) {
classElements[i].style.display = 'none';
}
thiselement.style.display='none';
thiselement.nextElementSibling.style.display='block';
}
function showcomment(thiselement){
var classElements = document.getElementsByClassName('comment');
for (var i=0; i<classElements.length; i++) {
classElements[i].style.display = 'inline';
}
thiselement.previousElementSibling.style.display='block';
thiselement.style.display='none';
}
function content_level_1(thiselement){
var i;
var navall = document.getElementsByTagName('nav')[0].childNodes[1].getElementsByTagName('li');
for (i=0; i<navall.length; i++) navall[i].style.display = 'none';
var navsec = document.getElementsByTagName('nav')[0].childNodes[1].childNodes;
for (i=1; i<navsec.length; i+=2) navsec[i].style.display = 'block';
thiselement.style.display='none';
thiselement.nextElementSibling.style.display='block';
}
function content_level_2(thiselement){
var i,j;
var navall = document.getElementsByTagName('nav')[0].childNodes[1].getElementsByTagName('li');
for (i=0; i<navall.length; i++) {
navall[i].style.display = 'none';
}
var navsec = document.getElementsByTagName('nav')[0].childNodes[1].childNodes;
var navsubsec;
navsec[1].style.display = 'block';
navsec[3].style.display = 'block';
navsubsec = navsec[3].childNodes[2].childNodes;
for (j=1; j<navsubsec.length; j+=2) navsubsec[j].style.display = 'block';
for (i=5; i<navsec.length; i+=2) {
navsec[i].style.display = 'block';
if(navsec[i].childNodes.length>=2){
navsubsec = navsec[i].childNodes[1].childNodes;
for (j=1; j<navsubsec.length; j+=2) navsubsec[j].style.display = 'block';
}
}
thiselement.style.display='none';
thiselement.nextElementSibling.style.display='block';
}
function content_level_3(thiselement){
var i;
var navall = document.getElementsByTagName('nav')[0].childNodes[1].getElementsByTagName('li');
for (i=0; i<navall.length; i++) navall[i].style.display = 'block';
thiselement.style.display='none';
thiselement.previousElementSibling.previousElementSibling.style.display='block';
}
function loadpage(){
var files=document.getElementsByClassName("file");
for (var i=0;i<files.length;i++) {
files[i].onclick=function (){
var j=1;
if (this.nextElementSibling.style.display=='none') j=0;
if (j==1) this.nextElementSibling.style.display='none';
else this.nextElementSibling.style.display='block';
}
}
}
</script>
<!-- <style>
html{
filter: grayscale(100%);
-webkit-filter: grayscale(100%);
-moz-filter: grayscale(100%);
-ms-filter: grayscale(100%);
-o-filter: grayscale(100%);
}
</style> -->
</head>
<body onload="loadpage();">
<nav>
<ul>
<li><a href="#引言" style="font-weight: bold; text-align: center;">理论篇</a></li>
<li>
<a href="#引言">§1. 引言</a><ul>
<li><a href="#命令基础">§1.1. 命令基础</a></li>
<li><a href="#工具准备">§1.2. 工具准备</a><ul>
<li><a href="#文本编辑器">§1.2.1. 文本编辑器</a></li>
<li><a href="#压缩软件">§1.2.2. 压缩软件</a></li>
<li><a href="#NBT_编辑器">§1.2.3. NBT 编辑器</a></li>
<li><a href="#绘图工具">§1.2.4. 绘图工具</a></li>
</ul></li>
<li><a href="#文件结构">§1.3. 游戏文件夹</a></li>
<li><a href="#JSON文件">§1.4. JSON文件</a></li>
</ul></li>
<li><a href="#数据包">§2 数据包</a><ul>
<li><a href="#数据包/元信息和图标">§2.1 元信息和图标</a></li>
<li><a href="#数据包/命名空间">§2.2 命名空间</a></li>
<li><a href="#函数">§2.3 函数</a></li>
<li><a href="#进度">§2.4 进度</a></li>
<li><a href="#战利品表">§2.5 战利品表</a></li>
<li><a href="#战利品表谓词">§2.6 战利品表谓词</a></li>
<li><a href="#物品修饰器">§2.7 物品修饰器</a></li>
<li><a href="#配方">§2.8 配方</a><ul>
<li><a href="#有序合成">§2.8.1 有序合成</a></li>
<li><a href="#无序合成">§2.8.2 无序合成</a></li>
<li><a href="#切石机配方">§2.8.3 切石机配方</a></li>
<li><a href="#烧炼配方">§2.8.4 烧炼配方</a></li>
<li><a href="#锻造台配方">§2.8.5 锻造台配方</a></li>
<li><a href="#工作台特殊配方">§2.8.6 工作台特殊配方</a></li>
<li><a href="#覆盖原版配方">§2.8.7 覆盖原版配方</a></li>
<li><a href="#配方获取">§2.8.8 配方获取</a></li>
</ul></li>
<li><a href="#结构">§2.9 结构</a></li>
<li><a href="#标签">§2.10 标签</a><ul>
<li><a href="#方块标签">§2.10.1 方块标签</a></li>
<li><a href="#物品标签">§2.10.2 物品标签</a></li>
<li><a href="#函数标签">§2.10.3 函数标签</a></li>
<li><a href="#实体类型标签">§2.10.4 实体类型标签</a></li>
<li><a href="#流体标签">§2.10.5 流体标签</a></li>
<li><a href="#游戏事件标签">§2.10.6 游戏事件标签</a></li>
</ul></li>
<li><a href="#维度和维度类型">§2.11 维度和维度类型</a><ul>
<li><a href="#维度">§2.11.1 维度</a></li>
<li><a href="#维度类型">§2.11.2 维度类型</a></li>
<li><a href="#维度实例">§2.11.3 实例</a></li>
<li><a href="#自定义世界">§2.11.4 自定义世界</a></li>
</ul></li>
<li><a href="#自定义世界生成">§2.12 自定义世界生成</a><ul>
<li><a href="#噪声设置">§2.12.1 噪声设置</a></li>
<li><a href="#生物群系">§2.12.2 生物群系</a></li>
<li><a href="#地形雕刻器">§2.12.3 地形雕刻器</a></li>
<li><a href="#地表生成器">§2.12.4 地表生成器</a></li>
<li><a href="#地物">§2.12.5 地物</a><ul>
<li><a href="#地物/JSON格式">JSON格式</a></li>
<li><a href="#可用的地物">可用的地物</a></li>
<li><a href="#装饰物">装饰物</a></li>
<li><a href="#可用的装饰物">可用的装饰物</a></li>
</ul></li>
<li><a href="#结构地物">§2.12.6 结构地物</a><ul>
<li><a href="#结构地物/JSON格式">JSON格式</a></li>
<li><a href="#可用的结构地物">可用的结构地物</a></li>
</ul></li>
<li><a href="#模板池">§2.12.8 模板池</a></li>
<li><a href="#处理器列表">§2.12.9 处理器列表</a><ul>
<li><a href="#处理器列表/JSON格式">JSON格式</a></li>
<li><a href="#可用的处理器列表">可用的处理器列表</a></li>
</ul></li>
</ul></li>
</ul></li>
<li><a href="#资源包">§3 资源包</a><ul>
<li><a href="#资源包/元信息和图标">§3.1 元信息和图标</a></li>
<li><a href="#资源包/命名空间">§3.2 命名空间</a></li>
<li><a href="#语言文件">§3.3 语言文件</a></li>
<li><a href="#自定义物品模型">§3.4 自定义物品模型</a></li>
<li><a href="#模型">§3.5 模型</a></li>
<li><a href="#纹理">§3.6 纹理</a></li>
<li><a href="#音效">§3.7 音效</a></li>
<li><a href="#字体">§3.8 字体</a></li>
<li><a href="#着色器">§3.9 着色器</a><ul>
<li><a href="#后处理着色器">§3.9.1 后处理着色器</a></li>
<li><a href="#核心着色器">§3.9.2 核心着色器</a></li>
</ul></li>
<li><a href="#文本">§3.10 文本</a></li>
</ul></li>
<li><a href="#规划" style="font-weight: bold; text-align: center;">实践篇</a></li>
<li><a href="#规划">§4. 规划</a><ul>
<li><a href="#名称设计">§4.1 名称设计</a></li>
<li><a href="#调试">§4.2 调试</a></li>
<li><a href="#前置与附属">§4.3 前置与附属</a></li>
<li><a href="#发布">§4.4 发布</a></li>
</ul></li>
<li><a href="#物品设计">§5 物品设计</a><ul>
<li><a href="#通用处理">§5.1 通用处理</a></li>
<li><a href="#右键交互">§5.2 右键交互</a></li>
<li><a href="#食物">§5.3 食物</a></li>
<li><a href="#药水">§5.4 药水</a></li>
<li><a href="#自定义状态效果">§5.5 自定义状态效果</a></li>
<li><a href="#头饰">§5.6 头饰</a></li>
<li><a href="#盔甲">§5.7 盔甲</a></li>
<li><a href="#工具和武器">§5.8 工具和武器</a></li>
<li><a href="#画">§5.9 画</a></li>
</ul></li>
<li><a href="#方块设计">§6 方块设计</a><ul>
<li><a href="#视线追踪法">§6.1 视线追踪法</a></li>
<li><a href="#计算交点法">§6.2 计算交点法</a></li>
<li><a href="#命令方块替换法">§6.3 命令方块替换法</a></li>
<li><a href="#破坏事件">§6.4 破坏事件</a></li>
<li><a href="#模型设置">§6.5 模型设置</a></li>
</ul></li>
<li><a href="#机器设计">§7 机器设计</a><ul>
<li><a href="#GUI纹理模型">§7.1 GUI纹理模型</a></li>
<li><a href="#GUI背景处理">§7.2 GUI背景处理</a></li>
<li><a href="#GUI命令">§7.3 GUI命令</a></li>
<li><a href="#物品输出">§7.4 物品输出</a></li>
<li><a href="#配方处理">§7.5 配方处理</a></li>
<li><a href="#插件">§7.6 插件</a></li>
<li><a href="#容器扩展">§7.7 容器扩展</a></li>
<li><a href="#接口">§7.8 接口</a></li>
<li><a href="#管道">§7.9 管道</a><ul>
<li><a href="#无线传输">§7.9.1 无线传输</a></li>
<li><a href="#管道式">§7.9.2 管道式</a></li>
<li><a href="#激光式">§7.9.3 激光式</a></li>
<li><a href="#载体式">§7.9.4 载体式</a></li>
<li><a href="#管道设计">§7.9.5 管道设计</a></li>
</ul></li>
</ul></li>
<li><a href="#NBT合成与烧炼">§8 NBT合成与烧炼</a><ul>
<li><a href="#地板合成">§8.1 地板合成</a></li>
<li><a href="#实体背包合成">§8.2 实体背包合成</a></li>
<li><a href="#容器合成">§8.3 容器合成</a></li>
<li><a href="#NBT烧炼">§8.4 NBT烧炼</a><ul>
<li><a href="#替换产物法">§8.4.1 替换产物法</a></li>
<li><a href="#记分板模拟">§8.4.2 记分板模拟</a></li>
</ul></li>
<li><a href="#NBT酿造">§8.5 NBT酿造</a></li>
</ul></li>
<li><a href="#植物">§9 植物</a><ul>
<li><a href="#作物">§9.1 作物</a></li>
<li><a href="#花草">§9.2 花草</a></li>
<li><a href="#树">§9.3 树</a></li>
</ul></li>
<li><a href="#物品与实体处理">§10 物品与实体处理</a><ul>
<li><a href="#修改玩家背包">§10.1 修改玩家背包</a></li>
<li><a href="#耐久处理">§10.2 耐久处理</a></li>
<li><a href="#红石信号">§10.3 红石信号</a></li>
<li><a href="#方块交互">§10.4 方块交互</a></li>
<li><a href="#生物移动">§10.5 生物移动</a></li>
<li><a href="#交易">§10.6 交易</a></li>
<li><a href="#清理特定物品">§10.7 清理特定物品</a></li>
<li><a href="#连锁">§10.8 连锁</a></li>
</ul></li>
<li><a href="#算法">§11 算法</a><ul>
<li><a href="#随机数">§11.1 随机数</a><ul>
<li><a href="#不定长均匀分布">§11.1.1 不定长均匀分布</a></li>
<li><a href="#定长均匀分布">§11.1.2 定长均匀分布</a></li>
<li><a href="#非均匀分布">§11.1.3 非均匀分布</a></li>
<li><a href="#二项分布和泊松分布">§11.1.4 二项分布</a></li>
</ul></li>
<li><a href="#世界生成结构">§11.2 世界生成结构</a><ul>
<li><a href="#自定义地物">§11.2.1 自定义地物</a></li>
<li><a href="#任意纯方块结构">§11.2.2 任意纯方块结构</a></li>
<li><a href="#含实体结构">§11.2.3 含实体结构</a></li>
<li><a href="#区块标记法">§11.2.4 区块标记法</a></li>
</ul></li>
<li><a href="#维度探测">§11.3 维度探测</a></li>
<li><a href="#绘制图案">§11.4 绘制图案</a></li>
<li><a href="#循环与递归">§11.5 循环与递归</a></li>
<li><a href="#字符操作">§11.6 字符操作</a></li>
<li><a href="#位运算与种子">§11.7 位运算与种子</a></li>
<li><a></a></li>
</ul></li>
</ul>
<footer id="options">
<div style="background-color: rgb(0,0,129);" onclick="content_level_1(this);" title="显示目录全部层次">全</div>
<div style="background-color: rgb(0,0,129);display:none;" onclick="content_level_2(this)" title="显示目录节">节</div>
<div style="background-color: rgb(0,0,129);display:none;" onclick="content_level_3(this);" title="显示目录小节">小</div>
<div style="background-color: rgb(0,129,0);" onclick="hidecomment(this);" title="显示JSON注释">显</div>
<div style="background-color: rgb(0,129,0);display:none;" onclick="showcomment(this)" title="隐藏JSON注释">隐</div>
</footer>
<footer id="sign">
<p class="noindent" style="font-size:100%;margin:0; text-align:right;color: hsl(220, 90%, 90%);">ruhuasiyu</p>
</footer>
</nav>
<div id="main_part">
<img id="banner" src="items/banner.png" alt="原版模组入门教程" style="width:100%;"/>
<article>
<p style="font-style: italic;">最后更新于 2022/04/23</p>
<h1 id="引言">§1 引言</h1>
<p>原版模组指在不修改 Minecraft 游戏本体的前提下,通过命令方块、一键命令、数据包、资源包等方式对游戏的可玩性做出修改。之所以称之为原版模组,乃是为了和使用 Mod Loader/API 环境基于 Java 开发的 Mod 作区分,这些 Mod Loader/API 包括 Forge,Liteloader,Fabric 等。自 Minecraft Java 版 1.13 起的数据包概念问世之后,原版模组的制作已变得十分便捷。本文内的原版模组便是指利用数据包和可能的配套资源包对游戏的可玩性做出修改。</p>
<p>本文内容适用于 Minecraft Java 版 1.19 版本,但大部分内容也适合 1.13-1.18 版本,或只需要做简单修改,请读者自行区分。系统环境为 Windows 10,其它环境下有较小的差异。本文参考和吸取了大量其他玩家的意见、建议和教程等,无法一一列出,在此一并表示感谢。</p>
<p>本文更侧重教程而非开发手册,因此很多内容的完整格式并没有列出,此时请读者自行查阅相关的<a href="https://zh.minecraft.wiki">中文 Minecraft Wiki</a> 链接。由于<a href="https://minecraft.wiki">英文 Minecraft Wiki</a> 往往更新更及时且内容更准确,因此有英文阅读能力的可直接查看英文 wiki 的相关内容。</p>
<p>本文中<code><i>青铜色楷体</i></code>表示其应当被替换为合适的字符串,<code style="color: rgb(0,129,0);">绿色楷体</code>表示JSON文件中的注释,点击左下角<span style="color:white;background-color: rgb(0,129,0);font-weight: bold;">显</span>/<span style="color:white;background-color: rgb(0,129,0);font-weight: bold;">隐</span>可切换显示或隐藏注释。</p>
<h2 id="命令基础">§1.1 命令基础</h2>
<p>本文不会介绍命令的基础知识,相关内容请读者通过如下链接自行了解。</p>
<ul>
<li><a href="https://zh.minecraft.wiki/w/命令">命令</a>
此为官方 wiki 的命令页面,其中包括了命令的基本参数介绍:坐标、目标选择器、数据标签 (NBT) 、原始JSON文本、命名空间ID等内容。读者需在学习命令过程中逐步了解这些概念。</li>
<li><a href="https://zh.minecraft.wiki/w/记分板">记分板</a>
此为官方 wiki 的记分板页面,其中包括了记分板的所有准则和相关命令格式,也包含了标签 (tag) 和组 (team) 的相关内容。</li>
<li><a href="https://zh.minecraft.wiki/w/实体格式">实体格式</a>和<a href="https://zh.minecraft.wiki/w/Player.dat格式">player.dat格式</a>
这两个页面给出了所有物品和实体(含方块实体)的 NBT。在游戏中,实体的 NBT 可通过命令 <code>data get entity/block</code> 来获取,物品的 NBT 可通过手持并输入命令 <code>data get entity @s SelectedItem</code> 来获取,以避免记忆大量的 NBT。</li>
<li><a href="https://commandtutorials.neocities.org/">新人手册-MC命令方块资源</a>
该网站包含了很多基础的教程,不过很多内容会有些过时。还包含少量进阶的内容,对于初学者可能较为复杂,请以理解其逻辑为主。</li>
<li><a href="http://mc-command.oschina.io/command-tutorial/">命令进阶</a>
该网站虽名为命令进阶,实际上比前一项页面更为初等,不过更为系统。</li>
</ul>
<p>若你已对 1.18 之前版本的命令较为熟悉,可在<a href="https://zh.minecraft.wiki/w/Java版版本记录">Java版版本记录</a>中查看各版本间差异。</p>
<h2 id="工具准备">§1.2 工具准备</h2>
<h3 id="文本编辑器">§1.2.1 文本编辑器</h3>
<p>原版模组涉及的文本文件,包括文本文档(.txt)、函数文件(.mcfunction)、JSON文件(.json, .mcmeta)、顶点着色器(.vsh)和片段着色器(.fsh),均需使用 <code>UTF-8</code> 编码格式。注意不要误选了 <code>UTF-8 with BOM</code> 编码格式。文本编辑器多如瀚海,读者可自行选择一种。我仅列出本人常用的两个文本编辑器。</p>
<ul>
<li><a href="https://code.visualstudio.com/">Visual Studio Code</a> 下载安装后,可以安装插件 <em>Chinese (Simplified) Language Pack for Visual Studio Code</em> 以支持中文语言,以及<em>Data-pack Helper Plus</em> 用于数据包各项内容的语法补全和纠错。</li>
<li>记事本为 Windows 系统自带的极简编辑器。Windows10 的记事本已经默认是 <code>UTF-8</code> 编码了。点击<code>查看->状态栏</code>可以在右下角状态栏看到,因此可以正常使用。旧版本 Windows 的记事本仍然不是,请勿使用。</li>
<!--<li><a href="https://notepad-plus-plus.org/">Notepad++</a>复杂程度介于二者之间。可从 <a href="http://www.mcbbs.net/thread-806816-1-1.html">mcfunction 的语言样式和自动补全</a>帖中下载相关文件并导入以支持语法高亮和补全。另外请将 Notepad++ 中<code>设置->首选项->其它->自动检测字符编码</code>选项关闭。</li>-->
</ul>
<p>编辑器右下角可以看到 <code>LF</code> 或 <code>CRLF</code>,分别表示两种换行符,二者均可正常使用,建议使用 <code>LF</code>。</p>
<p>为便于查看文件后缀,请将<code>文件->文件夹选项->查看->隐藏已知文件类型的扩展名</code>去掉勾选。我们可以在编辑器中新建文本文件,或者在文件夹中<code>右键->新建->文本文档</code>,除 <code>txt</code> 以外的文本文件可通过修改文件后缀得到。</p>
<h3 id="压缩软件">§1.2.2 压缩软件</h3>
<p>数据包和资源包均可以为文件夹或 zip 文件,zip 文件需要压缩软件来打开和制作。游戏本体和模组本体的 jar 文件也需要使用压缩软件来打开。常见的压缩软件有:</p>
<ul>
<li><a href="http://www.7-zip.org/">7-Zip</a> 是一款免费的压缩软件。jar 文件可以通过<code>右键->7-zip->打开压缩包</code>来打开。</li>
<li><a href="http://www.winrar.com.cn/">WinRAR</a> 是一款付费的压缩软件。</li>
<li>Windows 资源管理器是 Windows10 系统自带的软件。它可以使得 zip 文件如同文件夹般直接打开,压缩则用<code>选择->右键->发送到->压缩文件夹</code>,但它的压缩速度十分缓慢。</li>
</ul>
<h3 id="NBT_编辑器">§1.2.3 NBT 编辑器</h3>
<p>我们可以使用 <a href="https://github.com/tryashtar/nbt-studio/releases/">NBTStudio</a> 来打开 dat 文件和其它 NBT 格式文件。</p>
<h3 id="绘图工具">§1.2.4 绘图工具</h3>
<p>我们可以使用 <a href="https://www.adobe.com/cn/products/photoshop.html">Adobe Photoshop</a> 或其它绘图工具来绘制纹理。Windows 自带的画图由于无法生成透明背景,因此不建议使用。</p>
<h2 id="文件结构">§1.3 游戏文件夹</h2>
<p>本节中我们将对游戏文件夹的结构做简单的介绍,我们只介绍原版模组开发中涉及的内容。<code>.minecraft</code> 文件夹是 Minecraft 创建的并用于游戏运行的文件夹,它包含了游戏的所有内容。在第一次启动启动器时,会自动创建 <code>.minecraft</code> 文件夹。参考 <a href="https://zh.minecraft.wiki/w/.minecraft" class="wiki">.minecraft</a>。</p>
<p><code>.minecraft</code> 文件夹通常位于你的启动器目录下。如果启动器中设置为各版本独立,则位于 <code>versions/<i>版本号</i></code>下。另一种方式是在游戏内点击<code>选项->资源包->打开压缩包文件夹</code>并返回上级目录,或者点击<code>单人游戏->选中世界->编辑->打开世界文件夹</code>并返回上上级目录。</p>
<p class="noindent" id="游戏本体"><strong>游戏本体</strong>位于 <code>versions/<i>版本号</i>/<i>版本号</i>.jar</code>。该文件包含了对应版本的游戏资源和数据文件,使用压缩软件打开后,可以看到</p>
<ul>
<li>原版<a href="#资源包">资源包</a>位于 <code>assets</code> 文件夹内,其中 <code>minecraft</code> 文件夹为命名空间 <code>minecraft</code> 下的资源文件。</li>
<li>原版<a href="#数据包">数据包</a>位于 <code>data</code> 文件夹内,其中 <code>minecraft</code> 文件夹为命名空间 <code>minecraft</code> 下的数据文件。</li>
<li><code>pack.mcmeta</code> 为原版资源包和数据包的<a href="#数据包/元信息和图标">元信息</a>,1.17版本起不再包含该文件。</li>
<li><code>pack.png</code> 为原版资源包和数据包的<a href="#数据包/元信息和图标">图标</a>。</li>
</ul>
<figure>
<img src="items/游戏本体文件结构.png" alt="游戏本体文件结构" />
<figcaption>图1.1 游戏本体文件结构</figcaption>
</figure>
<p class="noindent" id="资源包文件夹"><strong>资源包文件夹</strong>位于 <code>resourcepacks</code>,其下方子文件夹或 <code>zip</code> 文件即为一个资源包,具体结构见<a href="#资源包">资源包</a>。服务器下载的资源包位于 <code>server-resource-packs/<i>服务器</i></code>,可使用压缩软件打开。</p>
<p class="noindent" id="资源文件"><strong>资源文件</strong> 部分资源文件不被包含在原版资源包内,而是位于资源文件夹下,这主要包括各种语言文本和音效文件。资源文件索引位于 <code>assets/indexes/<i>版本号</i>.json</code>,打开后通过键值可知相应资源的 hash 值,对应的资源位于 <code>assets/objects/<i>hash前2位</i>/<i>hash</i></code>。例如打开 <code>assets/indexes/1.17.json</code>,找到键 <code>minecraft/lang/zh_cn.json</code> 的 <code>hash</code> 为 <code>8fb4f6725d8317a37e7f823ff424e66a46b9ef75</code>,因此简体中文的语言文本位于文件夹 <code>assets/objects/8f/8fb4f6725d8317a37e7f823ff424e66a46b9ef75</code>,使用文本编辑器打开即可看到游戏内的所有名称的中文译名。注意该文件中的中文均被转化成了相应的 Unicode 表达方式,参考<a href="#字体">字体</a>。</p>
<p class="noindent"><strong>日志</strong>位于 <code>logs/latest.log</code>,可由此实时查看游戏运行中的各种反馈。对于我们而言,它可以在加载资源包和数据包时告诉我们它们是否有错误以及错误信息,包括错误的文件名称、位置、错误的行列数等,因此这对于我们调试非常重要。简体中文下需要设置文件编码为 <code>gbk</code>,否则除 ASCII 外的字符会显示乱码。历史日志位于 <code>logs/<i>年</i>-<i>月</i>-<i>日</i>-<i>序号</i>.log.gz</code>,使用压缩软件打开后使用文本编辑器打开即可查看。崩溃报告位于 <code>crash-reports/crash-<i>年</i>-<i>月</i>-<i>日</i>_<i>时</i>.<i>分</i>.<i>秒</i>-server.txt</code>,如果是由于资源包或数据包引起的崩溃,可以在该文件中看到原因。</p>
<p class="noindent"><strong>存储的物品栏</strong>位于 <code>hotbar.nbt</code>,存储了游戏内使用 <code>C+<i>数字</i></code> 存储、<code>X+<i>数字</i></code> 取出的创造模式物品快捷栏。</p>
<p class="noindent"><strong>存档文件</strong>位于 <code>saves/<i>世界名称</i></code>,由于<a href="https://zh.minecraft.wiki/w/世界格式">世界格式</a>上该内容已较为详尽且与原版模组联系甚远,因此我们仅提及部分内容。该文件夹包含的区块文件、地图文件等内容虽然也可以使用 NBT 编辑器来编辑,但较为不便,我们建议使用 MCEdit、地图文件生成工具等专门的工具来编辑。存档的备份文件位于 <code>backups/<i>年</i>-<i>月</i>-<i>日</i>_<i>时</i>.<i>分</i>.<i>秒</i>_<i>世界名称</i>.zip</code>,为存档的备份文件,解压后复制到 <code>saves</code> 即可使用。</p>
<ul>
<li><strong>进度</strong>位于 <code>advancements/<i>玩家UUID</i>.json</code>,记录了玩家已完成的进度和进度判据的完成时间。对于需要完成多个判据才能达成的进度,该文件中记录了已完成的那些判据的完成时间。</li>
<li><strong><a href="https://zh.minecraft.wiki/w/%E5%8C%BA%E5%9D%97%E6%A0%BC%E5%BC%8F">区块</a>、实体、实体兴趣点、<a href="https://zh.minecraft.wiki/w/Raids.dat%E6%A0%BC%E5%BC%8F">袭击</a></strong>等信息分维度存储,主世界、下界、末地、自定义维度的相应文件分别位于根文件夹、<code>DIM-1</code>、<code>DIM1</code>、<code>dimensions/<i>命名空间</i>/<i>路径</i></code>下。</li>
<li><strong>世界信息</strong>文件 <code>level.dat</code> 中 <code>WorldGenSettings</code> 包含了世界生成时的所有维度的生成信息,玩家可以在<code>创建新的世界->更多世界的选项->导入设置</code>使用JSON文件导入,格式见<a href="#自定义世界">自定义世界</a>。之后还会加入数据包中的自定义维度。</li>
<li><strong>数据包文件夹</strong>位于 <code>datapacks</code>,其下方子文件夹或 <code>zip</code> 文件即为一个数据包,具体结构见<a href="#数据包">数据包</a>。</li>
<li><strong>结构</strong>位于 <code>generated/<i>命名空间</i>/structures/<i>文件</i>.nbt</code>,其记录了游戏内使用结构方块保存的结构,将其移动至数据包内方可使用。</li>
</ul>
<h3 id="JSON文件">§1.4 JSON文件</h3>
<p>参考<a href="https://zh.minecraft.wiki/w/JSON" class="wiki">JSON</a>。数据包的进度、战利品表、战利品表谓词、物品修饰器、配方、标签、维度、维度类型、自定义世界生成,资源包的语言文件、模型、音效、字体、<code>credits.json</code> 等文件均为JSON文件。<code>.mcmeta</code> 文件也是JSON文件,因此格式也是相同的。</p>
<p>JSON文件中用于分割的空格、制表符(Tab)、回车和换行符都是可去的,它们仅用于提高可读性。编写时,使用空格或制表符缩进,以便于查看括号匹配和层次。JSON文件通常包含用于封装文件数据的一对大括号<code>{}</code>,即它是一个JSON对象,但<a href="#战利品表谓词">战利品表谓词</a>和<a href="#物品修饰器">物品修饰器</a>文件的根数据类型还可以为JSON数组。它包含类似 <code>"abc": "def"</code> 这样的 <code>"键": 值</code> 对,一般使用单引号也可以。同一个文件中如果允许有相同的键,则后者会覆盖前者。</p>
<p>JSON数据类型有下述几种。Wiki 上有关页面使用了 NBT 的数据类型标注,但其实并不适用于JSON文件,我们应当将其视为相应内容的可取值范围。</p>
<p class="noindent"><strong id="JSON布尔型">布尔型</strong>,值为 <code>true</code> 和 <code>false</code>。</p>
<pre>
{
"is_on_fire": false,
"is_baby": true,
"noise_caves_enabled": false
}
</pre>
<p class="noindent"><strong id="JSON数值">数值</strong>,值为任何数字。<code>2</code> 和 <code>2.0</code> 没有差异。</p>
<pre>
{
"count": 2.0,
"chance": 0.025,
"salt": 14357619
}
</pre>
<p class="noindent"><strong id="JSON字符串">字符串</strong>,值使用双引号/单引号圈住,可以使用颜色代码如 <code>§6</code>、换行符 <code>\n</code>。</p>
<pre>
{
"condition": "minecraft:random_chance",
"tag": "minecraft:wools",
"layer0": "cpp:crop/bauhinia_seeds"
}
</pre>
<p class="noindent"><strong id="JSON数组">数组</strong>,值使用中括号圈住。</p>
<pre>
{
"scale": [
0.901,
0.901,
0.901
],
"items": [
"minecraft:zombie_head",
"minecraft:skeleton_skull",
"minecraft:wither_skeleton_skull",
"minecraft:creeper_head"
],
"requirements": [
[
"wing_of_sky",
"heart_of_crystal",
"nova_of_fire"
]
],
"terms":[
{
"condition": "minecraft:location_check",
"predicate": {
"biome": "minecraft:snowy_taiga"
}
},
{
"condition": "minecraft:location_check",
"predicate": {
"biome": "minecraft:snowy_taiga_mountains"
}
}
]
}
</pre>
<p class="noindent"><strong id="JSON对象">对象</strong>,使用大括号圈住。整个JSON文件内容本身就是一个JSON对象。</p>
<pre>
{
"count": {
"type": "minecraft:uniform",
"min": 1.0,
"max": 2.0
},
"modifiers": [
{
"name": "legs_armor",
"attribute": "generic.armor",
"operation": "addition",
"amount": 4,
"slot": "legs"
}
]
}
</pre>
<p>JSON中没有注释的语法,但可以使用不被使用的键来表示注释。通常使用 <code>"_comment", "_comment1", "_comment2"</code> 这种键。</p>
<pre>
{
"pools": [
{
"rolls": 1,
"entries": [
{
<span class="comment">"_comment": "咸味粽子",</span>
"type": "minecraft:item",
"name": "minecraft:cooked_cod",
"functions": [
{
"function": "minecraft:set_nbt",
"tag": "{display:{Name:'{\"italic\":false,\"translate\":\"item.cpp.zongzi_with_salt\"}',Lore:['{\"italic\":false,\"translate\":\"item.cpp.zongzi_with_salt\"}']},id:'cpp:zongzi_with_salt',CustomModelData:12970027}"
}
]
}
]
}
]
}
</pre>
<p>我们常常在JSON中用整数来表示RGB格式颜色,对应值为: <code>65536×R+256×G+B</code>。</p>
<h1 id="数据包">§2 数据包</h1>
<ul class="link">
<li><a href="https://zh.minecraft.wiki/w/数据包" class="wiki">数据包</a></li>
<li><a href="https://zh.minecraft.wiki/w/教程/安装数据包" class="wiki">教程/安装数据包</a></li>
<li><a href="https://zh.minecraft.wiki/w/教程/制作数据包" class="wiki">教程/制作数据包</a></li>
</ul>
<p>数据包 (datapacks) 可用于覆盖或添加新的函数、进度、战利品表、战利品表谓词、物品修饰器、配方、结构、标签、维度、维度类型和自定义世界生成。数据包文件夹位于 <code>.minecraft/saves/<i>世界名称</i>/datapacks</code>,其下方子文件夹或 <code>zip</code> 文件即为一个数据包。</p>
<p>安装数据包:单人游戏中,对于新创建的世界,在创建时点击<code>创建新的世界->世界预设->数据包</code>,将数据包拖入并选择至右侧即可。对于已生成的世界,选择你需要安装数据包的世界,点击<code>编辑->打开世界文件夹->打开文件夹 datapacks</code>,并将数据包 <code>.zip</code> 文件或文件夹放入其中。多人游戏中,打开<code>服务器文件夹->worlds->datapacks</code>文件夹,并将数据包 <code>.zip</code> 文件或文件夹放入其中。数据包放置好后,在首次生成该世界/重新进入该世界/下次服务器启动时会启用该数据包。管理员也可以输入 <code>/reload</code> 来加载数据包,但这不适用<a href="#维度">维度</a>和<a href="#自定义世界生成">自定义世界生成</a>。</p>
<p>原版数据包是 Minecraft 自带的一个默认开启的数据包,其 <code>data</code> 文件夹位于 <code>.minecraft/versions/<i>版本号</i>/<i>版本号</i>.jar/data</code>,其中包含的原版进度、战利品表、配方、结构和标签等内容,是制作数据包的文件样板。注意原版的维度和自定义世界生成不在该路径,可从<a href="vanilla_worldgen.zip">此处下载</a>这些内容。</p>
<p>对于创建世界时添加的数据包,可以在数据包选择页面调整加载次序。其它情形添加的数据包优先级最高,即最后加载。同时加入的数据包优先级则和文件名顺序相关。数据包的优先级顺序储存在文件 <code>level.dat</code> 中,可以通过 <code>/datapack</code> 命令查看或修改。在游戏中通过命令 <code>/datapack</code> 可以禁用/启用数据包,最后启用的优先级最高。由于数据包加载顺序不定,因此在制作数据包的过程中,尽量不要依赖数据包的加载顺序。原版数据包的优先级一般是最低的。</p>
<p>使用 <code>/datapack list</code> 命令显示数据包名称时,原版数据包为 <code>[vanilla]</code>,玩家自定义的数据包为 <code>[file/<i>数据包名称</i>]</code>。</p>
<p class="noindent"><strong>文件夹结构</strong></p>
<pre class="file">datapacks/<i>数据包名称</i>或<i>数据包名称</i>.zip/</pre>
<pre>
pack.mcmeta
pack.png
data
<i>命名空间</i>
advancements
<i>进度名称</i>.json
functions
<i>函数名称</i>.mcfunction
loot_tables
<i>战利品表名称</i>.json
predicates
<i>战利品表谓词名称</i>.json
item_modifiers
<i>物品修饰器名称</i>.json
structures
<i>结构名称</i>.nbt
recipes
<i>配方名称</i>.json
tags
functions
<i>函数标签名称</i>.json
blocks
<i>方块标签名称</i>.json
items
<i>物品标签名称</i>.json
entity_types
<i>实体类型标签名称</i>.json
fluids
<i>流体标签名称</i>.json
game_events
<i>游戏事件标签名称</i>.json
dimension
<i>维度名称</i>.json
dimension_type
<i>维度类型名称</i>.json
worldgen
noise_settings
<i>噪声设置名称</i>.json
biome
<i>生物群系名称</i>.json
configured_carver
<i>地形雕刻器名称</i>.json
configured_surface_builder
<i>地表生成器名称</i>.json
configured_feature
<i>地物名称</i>.json
configured_structure_feature
<i>结构地物名称</i>.json
template_pool
<i>模板池名称</i>.json
processor_list
<i>处理器列表名称</i>.json
</pre>
<p>由于命名空间ID的命名要求,<code>data</code> 下所有文件和文件夹可使用的字符为 <code>_-.abcdefghijklmnopqrstuvwxyz0123456789</code>,<strong>不可使用大写字母、空格或中文</strong>,所有文本文件使用 <code>UTF-8</code> 编码。为了便于传播,发布时可将所有内容压缩为一个 <code>zip</code> 文件。压缩和解压的时候,注意文件层次,应当打开 <code>zip</code> 文件就可以看到数据包的 <code>pack.mcmeta</code>。稳妥的做法是 <code>打开文件夹->全选->右键->发送到->压缩文件夹</code> 或 <code>打开文件夹->全选->7-Zip->添加到 "<i>文件夹名</i>.zip"</code>。文件夹格式的数据包若有错误文件仍可以加载,但 <code>zip</code> 格式的会无法加载。</p>
<h2 id="数据包/元信息和图标">§2.1 元信息和图标</h2>
<p>Minecraft 通过文件 <code>pack.mcmeta</code> 来识别数据包,因此该文件是不可或缺的。例如:</p>
<pre class="file">pack.mcmeta</pre>
<pre>
{
"pack": {
"pack_format": 6, <span class="comment">数据包版本,1.13-1.14 版本为 4,1.15-1.16.1 版本为 5,1.16.2-1.16.5 版本为 6,1.17-1.17.1 版本为 7,1.18-1.18.1 版本为 8,1.18.2 版本为 9,1.19 版本为 10</span>
"description": [<span class="comment">数据包描述</span>
{
"text": "数据包名称",
"color": "green"
},
{
"text": "简要介绍\nby 某某作者",
"color": "gold"
}
]
},
"filter": {
"block": [<span class="comment">忽略相应命名空间下相应文件</span>
{
"namespace": "命名空间",
"path": "文件路径" <span class="comment">支持通用标识符 *</span>
}
]
}
}
</pre>
<p class="noindent">其中数据包描述为单个字符串或一个<a href="https://zh.minecraft.wiki/w/%E5%8E%9F%E5%A7%8BJSON%E6%96%87%E6%9C%AC%E6%A0%BC%E5%BC%8F">原始JSON文本</a>。创建新的世界时,它会显示在数据包菜单中数据包名称下方。在数据包列表下,光标移动到对应的数据包时会显示此处填写的描述。</p>
<p>1.16版本原版数据包里的 <code>pack.mcmeta</code> 文件为</p>
<pre class="file">pack.mcmeta</pre>
<pre>
{
"pack": {
"pack_format": 6,
"description": "The default data for Minecraft"
}
}
</pre>
<p>数据包可以包含一个 <a href="vanilla/pack.png"><code>pack.png</code></a>,它是正方形的图片,用于创建新的世界时在数据包菜单中显示。</p>
<h2 id="数据包/命名空间">§2.2 命名空间</h2>
<ul class="link">
<li><a href="https://zh.minecraft.wiki/w/命名空间" class="wiki">命名空间</a></li>
</ul>
<p>命名空间 (namespace) 为玩家自定义的、可操作的空间。使用独立的命名空间也有利于解决和他人的冲突。数据包下可以有多个命名空间,如果不同数据包中有相同的命名空间,则其中相同的文件名内容会根据加载先后顺序被覆盖。特别地,原版内容被保存在 <code>minecraft</code> 命名空间,想要修改和替换原版的内容只需在你的数据包内建立 <code>minecraft</code> 命名空间和相应的同名文件并修改即可。</p>
<p><a href="#标签">标签</a>文件,即 <code>tags</code> 中的文件内容默认追加而不是覆盖。因此标签文件是解决数据包冲突和联动的有力工具。</p>
<table><thead><tr><th>类型</th><th>调用格式(命名空间ID)</th><th>文件路径</th></tr></thead><tbody>
<tr>
<th>函数</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/functions/<i>路径</i>/<i>文件名</i>.mcfunction</code></td>
</tr>
<tr>
<th>进度</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/advancements/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>战利品表</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/loot_tables/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>战利品表谓词</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/predicates/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>物品修饰器</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/item_modifiers/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>配方</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/recipes/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>结构</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/strutures/<i>路径</i>/<i>文件名</i>.nbt</code></td>
</tr>
<tr>
<th>标签-方块</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/tags/blocks/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>标签-物品</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/tags/items/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>标签-函数</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/tags/functions/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>标签-实体类型</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/tags/entity_types/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>标签-流体类型</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/tags/fluids/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>标签-游戏事件</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/tags/game_events/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>维度</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/dimension/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>维度类型</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/dimension_type/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>世界生成-噪声设置</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/worldgen/noise_settings/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>世界生成-生物群系</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/worldgen/biome/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>世界生成-地形雕刻器</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/worldgen/configured_carver/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>世界生成-地表生成器</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/worldgen/configured_surface_builder/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>世界生成-地物</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/worldgen/configured_feature/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>世界生成-结构地物</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/worldgen/configured_structure_feature/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>世界生成-模板池</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/worldgen/template_pool/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
<tr>
<th>世界生成-处理器列表</th>
<td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td>
<td><code><i>命名空间</i>/worldgen/processor_list/<i>路径</i>/<i>文件名</i>.json</code></td>
</tr>
</tbody></table>
<p>1.16~1.16.1 版本的维度、维度类型和世界生成文件位置为 <code>minecraft/<i>类型</i>/<i>命名空间</i>/<i>路径</i>/<i>文件名</i>.json</code> 而不是 <code><i>命名空间</i>/<i>类型</i>/<i>路径</i>/<i>文件名</i>.json</code>。</p>
<p>若命名空间为 <code>minecraft</code>,则可直接省略 <code>minecraft:</code>。本文中我们会混用两种写法,注意区分。除此之外,如战利品表的 <code>type</code>、战利品表谓词的 <code>condition</code> 等诸多情形的值也是 <code>minecraft</code> 命名空间下的命名空间ID,因此此时也可以省略 <code>minecraft:</code>。</p>
<h2 id="函数">§2.3 函数</h2>
<table><tbody>
<tr><th>命名空间ID</th><td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td></tr>
<tr><th>文件路径</th><td><code><i>命名空间</i>/functions/<i>路径</i>/<i>文件名</i>.mcfunction</code></td></tr>
</tbody></table>
<ul class="link">
<li><a href="https://zh.minecraft.wiki/w/函数(Java版)" class="wiki">函数</a></li>
<li><a href="https://minecraft.wiki/w/Function_(Java_Edition)" class="wikien">Function</a></li>
</ul>
<p>函数 (Function) 是一系列顺次执行的命令列表,可以被命令 <code>function <i>命名空间ID</i></code> 来依次执行函数的每一条命令,还可被调用于<a href="#进度">进度</a>JSON文件的 <code>rewards->function</code>。函数每一行表示一个单独的命令,无需 <code>/</code> 开头。执行时会按顺序依次执行,使用 <code>#</code> 开头的行是注释。</p>
<p>如果函数被另一个函数执行,则默认无执行者,执行位置为出生点,除非在执行时继承调用它的函数的执行者和执行位置。如果函数被命令方块执行,则无执行者,执行位置为命令方块位置。如果函数被玩家手动执行,则执行者为玩家自身,执行位置为玩家位置。如果函数被进度奖励,执行者为完成进度的玩家,执行位置为玩家位置。这些情形下的执行者和执行位置均可使用<a href="https://zh.minecraft.wiki/w/命令/execute">命令</a> <code>execute</code> 来改变。</p>
<p>如果需要函数在游戏加载/每刻执行,则需要将其加入<a href="#函数标签">函数标签</a>中。</p>
<pre class="file" id="#cpp/functions/plants/vegt">cpp:plants/vegt</pre>
<pre>
<span class="comment">幻紫花</span>
execute as @s[tag=cpp_crop_purple_illusion] if predicate cpp:near_purple run function cpp:plants/vegt/purple_illusion
<span class="comment">稻谷</span>
execute as @s[tag=cpp_crop_rice] if block ~ ~-1 ~ farmland if predicate cpp:near_water run function cpp:plants/vegt/rice
<span class="comment">西红柿</span>
execute as @s[tag=cpp_crop_tomato] if block ~ ~-1 ~ farmland run function cpp:plants/vegt/fruit
<span class="comment">草莓</span>
execute as @s[tag=cpp_crop_strawberry] if block ~ ~-1 ~ farmland run function cpp:plants/vegt/fruit
<span class="comment">蓝莓</span>
execute as @s[tag=cpp_crop_blueberry] if block ~ ~-1 ~ podzol run function cpp:plants/vegt/fruit
<span class="comment">菠萝</span>
execute as @s[tag=cpp_crop_pineapple] if block ~ ~-1 ~ coarse_dirt if predicate cpp:near_water run function cpp:plants/vegt/fruit
</pre>
<h2 id="进度">§2.4 进度</h2>
<table><tbody>
<tr><th>命名空间ID</th><td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td></tr>
<tr><th>文件路径</th><td><code><i>命名空间</i>/advancements/<i>路径</i>/<i>文件名</i>.json</code></td></tr>
</tbody></table>
<ul class="link">
<li><a href="https://zh.minecraft.wiki/w/进度/JSON格式" class="wiki">进度</a></li>
<li><a href="https://minecraft.wiki/w/Advancement/JSON_format" class="wikien">Advancement</a></li>
</ul>
<p>进度 (Advancement) 为游戏内检测玩家行为,触发后完成并执行奖励的系统,游戏内按 <code>L</code> 即可查看,可被用作命令 <code>advancement</code> 的参数,以授予或移除玩家的特定进度。</p>
<p>注意1.17的物品谓词和方块谓词与旧版本的有差异。</p>
<pre class="file" id="进度JSON格式">进度JSON格式</pre>
<pre>
{
"display": { <span class="comment">可选,显示数据</span>
"icon": { <span class="comment">一个物品,用于显示进度的图标</span>
"item": "物品命名空间ID", <span class="comment">图标物品 ID</span>
"nbt": "字符串" <span class="comment">图标物品nbt标签,可能会影响图标,例如指定 CustomModelData</span>
},
"title": <a href="https://zh.minecraft.wiki/w/原始JSON文本格式">原始JSON文本</a>, <span class="comment">进度的名称</span>
"description": <a href="https://zh.minecraft.wiki/w/原始JSON文本格式">原始JSON文本</a>, <span class="comment">进度的描述</span>
"frame": "task" (默认) 或 "challenge" 或 "goal", <span class="comment">可选,图标边框,分别为方形边框(任务)、尖形边框(挑战)、圆形边框(目标)</span>
"background": "<a href="#纹理">纹理</a>命名空间ID", <span class="comment">仅根进度有,决定该选项卡的背景图</span>
"show_toast": true (默认值) 或 false, <span class="comment">可选,是否在完成此进度后显示提示信息,若无显示效果则无效。</span>
"announce_to_chat": true (默认值) 或 false, <span class="comment">可选,是否在完成此进度时在聊天窗口提示,若无显示效果则无效。</span>
"hidden": true 或 false (默认值), <span class="comment">可选,在进度屏幕隐藏此进度和子进度,直到完成进度。</span>
},
"parent": "<a href="#进度">进度</a>命名空间ID", <span class="comment">可选,表示上游进度</span>
"criteria": { <span class="comment">需要达成的条件</span>
"条件名称": { <span class="comment">其中一个条件</span>
"trigger": "触发器名称",
"conditions": { <span class="comment">该触发器达成时需要满足的条件</span>
}
}
},
"requirements": [ <span class="comment">可选,每一组条件中至少有一个达成时,该进度才会完成。默认所有条件都需要达成。</span>
[
"条件", ..., "条件"
],
[
"条件", ..., "条件"
]
],
"rewards": { <span class="comment">可选, 完成进度的奖励</span>
"function":
"<a href="#函数">函数</a>命名空间ID", <span class="comment">完成进度时执行该函数,不可为函数标签。</span>
"loot": [ <span class="comment">完成进度时给予玩家这些战利品表</span>
"<a href="#战利品表">战利品表</a>命名空间ID", ..., "<a href="#战利品表">战利品表</a>命名空间ID"
],
"recipes": [ <span class="comment">完成进度时玩家解锁这些配方</span>
"<a href="#配方">配方</a>命名空间ID", ..., "<a href="#配方">配方</a>命名空间ID"
],
"experience": 正整数 <span class="comment">完成进度时玩家获得的经验</span>
}
}
</pre>
<p>没有 <code>parent</code> 的进度被称为根进度。若其有 <code>display</code>,则它定义了一个进度的选项卡。</p>
<p>当一个进度没有 <code>display</code> 时,或者其上游的根进度没有 <code>display</code> 时,它不会显示在进度页面中。解锁配方的进度,以及我们只是用来实现某些效果而并非希望将其添加到进度页面的进度,应当省略 <code>display</code> 以隐藏之。</p>
<p>当进度需要所有的条件都达成时才能完成时,我们不需要定义 <code>requirements</code>,这等价于 <code>"requirements": [["条件 1"],["条件 2"],...,["条件 n"]]</code>。如果我们需要复杂的组合条件时,就需要使用该字段。<code>requirements</code> 的格式为或的与(合取范式),即其列表中的每一个项(该项还是一个条件的列表)中的均至少有一个条件满足。例如 <code>"requirements": [["条件 a", "条件 b"],["条件 c", "条件 d"]]</code> 表示当 <code>条件 a</code> 和 <code>条件 b</code> 至少有一个满足且 <code>条件 c</code> 和 <code>条件 d</code> 至少有一个满足时,进度会完成。不过较为常见的还是所有条件只要有一个满足即可,这时写作 <code>"requirements": [["条件 1","条件 2",...,"条件 n"]]</code>。例如下例中两个条件 <code>sealing_wand</code>, <code>dream_wand</code> 分别表示玩家获取了相应 NBT 物品的触发器,只要其中有一个满足即可完成进度。</p>
<pre class="file" id="cpp/advancements/wand">cpp/advancements/wand.json</pre>
<pre>
{
"parent": "cpp:root",
"display": {
"icon": {
"item": "minecraft:carrot_on_a_stick",
"nbt": "{CustomModelData:12970062}"
},
"title":{
"translate": "advancements.cpp.wand.title"
},
"description": {
"translate": "advancements.cpp.wand.description"
},
"frame": "challenge"
},
"criteria": {
"sealing_wand": {
"trigger": "minecraft:inventory_changed",
"conditions":{
"items":[
{
"nbt": "{id:\"cpp:sealing_wand\"}"
}
]
}
},
"dream_wand": {
"trigger": "minecraft:inventory_changed",
"conditions":{
"items":[
{
"nbt": "{id:\"cpp:dream_wand\"}"
}
]
}
}
},
"rewards": {
"experience": 200
},
"requirements": [
[
"mahoushoujo",
"dream_wand"
]
]
}</pre>
<p>完整的触发器和触发器的条件请查看<a href="https://zh.minecraft.wiki/w/进度/JSON格式#触发器列表">进度/JSON格式#触发器列表</a>。我们简要列出常见的触发器:</p>
<table><thead><tr><th>触发器</th><th>触发器的条件</th></tr></thead><tbody>
<tr>
<td><code>minecraft:impossible</code></td>
<td>仅可使用命令触发。这样的进度一般使用函数来判断并直接给予玩家。</td>
</tr>
<tr>
<td><code>minecraft:tick</code></td>
<td>每个游戏刻触发。常用于判断玩家是否是第一次进入游戏。也可用来仅需判断玩家的战利品表谓词来完成的进度,见下文。</td>
</tr>
<tr>
<td><code>minecraft:location</code></td>
<td>检查玩家的位置,例如玩家进入某个维度、生物群系、结构等,或者玩家进入某种流体、某个高度等。有些也可以用其它触发器实现。</td>
</tr>
<tr>
<td><code>minecraft:enter_block</code></td>
<td>玩家进入方块时触发,例如水、传送门、花等。</td>
</tr>
<tr>
<td><code>minecraft:placed_block</code></td>
<td>玩家放置方块时触发,例如玩家放置了木桶、熔炉、树苗等。在我们自定义方块时很有用。该进度被触发时,方块已经被放置在世界中但玩家手持的方块尚未被清除,因此可以检测玩家手持物的信息。</td>
</tr>
<tr>
<td><code>minecraft:inventory_changed</code></td>
<td>玩家物品栏变化时触发,例如玩家获取物品。</td>
</tr>
<tr>
<td><code>minecraft:consume_item</code></td>
<td>玩家消耗了相应物品,例如食用食物、饮用药水等。在我们自定义食物和药水时很有用。该进度被触发时,玩家手持的物品尚未被消耗,因此可以检测玩家手持物的信息。</td>
</tr>
<tr>
<td><code>minecraft:entity_hurt_player</code></td>
<td>实体伤害玩家时触发。</td>
</tr>
<tr>
<td><code>minecraft:entity_killed_player</code></td>
<td>实体杀死玩家时触发。</td>
</tr>
<tr>
<td><code>minecraft:player_hurt_entity</code></td>
<td>玩家伤害实体(包括自己)时触发。</td>
</tr>
<tr>
<td><code>minecraft:player_killed_entity</code></td>
<td>玩家杀死实体时触发。</td>
</tr>
<tr>
<td><code>minecraft:player_interacted_with_entity</code></td>
<td>玩家用手中物品与实体互动时触发,例如交易、修改实体数据(驯服、喂养、上鞍、剪羊毛、旋转物品展示框或放入物品、收集龙息、与猪灵换物、修补铁傀儡)、桶装牛奶、桶装鱼、碗装蘑菇煲、碗装迷之炖菜等。</td>
</tr>
<tr>
<td><code>minecraft:item_durability_changed</code></td>
<td>物品栏中任何物品以任何形式损害时触发,例如使用工具消耗了耐久。当使用拥有耐久附魔的工具而未消耗耐久时,不会触发。</td>
</tr>
<tr>
<td><code>minecraft:item_used_on_block</code></td>
<td>玩家对方块使用物品时触发,例如对着篝火放置食物、斧给木头剥皮、向花盆中放入花等改变目标方块数据的,或者右击告示牌,或者对着任意方块放置方块。</td>
</tr>
</tbody></table>
<p>所有的触发器条件均有一个可选的<a href="#战利品表谓词">战利品表谓词</a>列表 <code>player</code> 字段用于要求玩家额外需要满足的战利品表谓词。例如</p>
<pre class="file" id="cpp/functions/fatness">cpp:fatness</pre>
<pre>
{
"display": {
"icon": {
"item": "minecraft:enchanted_golden_apple"
},
"title":{
"translate": "advancements.cpp.fatness.title"
},
"description": {
"translate": "advancements.cpp.fatness.description"
},
"frame": "challenge"
},
"parent": "cpp:dream_wand",
"criteria": {
"fatness": {
"trigger": "minecraft:tick",
"conditions": {
"player": [
{
"condition": "minecraft:entity_scores",
"entity": "this",
"scores": {
"cppHealth": {
"min": 40
}
}
}
]
}
}
}
}</pre>
<p>奖励中的解锁配方一般适用于数据包添加的配方相应的解锁进度,这样的进度无需 <code>display</code> 字段,参考<a href="#配方">配方</a>。奖励中的经验建议仅在高难度进度完成时给予,这样的进度通常设置 <code>frame</code> 为挑战。奖励中的函数的执行者为完成进度的玩家,位置为玩家的位置。</p>
<p>游戏内或函数内使用 <code>advancement</code> 命令可以手动给予或剥夺进度。进度配合奖励函数剥夺玩家该进度,则该进度可反复触发,可用于诸如检测玩家生物群系、饮食、放置方块等需要循环检测的情形。这样的进度需要缺省 <code>display</code> 字段。例如:</p>
<pre class="file" id="cpp/advancements/food/citrus">cpp/advancements/food/citrus.json</pre>
<pre>
{
"criteria": {
"citrus": {
"trigger": "minecraft:consume_item",
"conditions": {
"item": {
"nbt": "{id:\"cpp:citrus\"}"
}
}
}
},
"rewards":{
"function": "<a href="#cpp/functions/diet/citrus.mcfunction">cpp:diet/citrus</a>"
}
}</pre>
<pre class="file" id="cpp/functions/diet/citrus.mcfunction">cpp:diet/citrus</pre>
<pre>
advancement revoke @s only <a href="#cpp/advancements/food/citrus">cpp:diet/citrus</a>
effect give @s saturation 1 1 true
</pre>
<p class="noindent"><strong id="原版进度">原版进度</strong> 如果需要修改原版的进度,只需要在数据包中添加相同路径的相应名称文件并修改之即可。原版的进度被划分为5个选项卡,命名空间ID分别为 <code>minecraft:story/*</code>, <code>minecraft:nether/*</code>, <code>minecraft:end/*</code>, <code>minecraft:adventure/*</code>, <code>minecraft:husbandry/*</code>。其中 <code>minecraft:nether/all_effects</code>, <code>minecraft:adventure/hero_of_the_village</code>, <code>minecraft:adventure/arbalistic</code> 为隐藏进度。这些进度没有奖励,或只有奖励经验值。</p>
<p>除此之外,原版获取配方的进度命名空间ID为 <code>minecraft:recipes/*</code>。</p>
<h2 id="战利品表">§2.5 战利品表</h2>
<table><tbody>
<tr><th>命名空间ID</th><td><code><i>命名空间</i>:<i>路径</i>/<i>文件名</i></code></td></tr>