官方维基教程-Data Patch:修订间差异
无编辑摘要 |
(→数据补丁) |
||
| 第1行: | 第1行: | ||
= 数据补丁 = | = 数据补丁 = | ||
数据补丁(Data Patches,旧称数据补丁,Content Patches,于v159更名)是一种强大的工具,可以针对每个地图或服务器修改方块、单位和物品的属性。该功能的应用包括平衡补丁、自定义游戏模式或不同的游戏进程。 | |||
数据补丁'''可以''做到: | |||
*增加或减少工厂的输入; | |||
* 增加或减少工厂的输入; | |||
* 改变方块的建造需求; | * 改变方块的建造需求; | ||
* 完全改变某单位的武器和子弹; | * 完全改变某单位的武器和子弹; | ||
| 第12行: | 第11行: | ||
* 改变任意方块的建造速度、生命值、或装甲等等; | * 改变任意方块的建造速度、生命值、或装甲等等; | ||
* 改变单位的类型,如从陆军变为空军。 | * 改变单位的类型,如从陆军变为空军。 | ||
* 向游戏中添加新纹理或资源文件; | |||
* 添加新内容,如方块、单位等; | |||
数据补丁'''无法'''做到: | |||
* 添加原版没有的新机制;(译者注:JSON模组只能根据原版已有的架构进行编辑,因此数据补丁同理) | |||
* 改变方块的类型,如把墙变成炮塔;(译者注:原因如上) | |||
尽管平衡补丁有着堪比JSON模组的能力,但它仍然''不是''模组的替代器(译者注:指一般性的内容模组)(尤其是JAVA模组) | |||
= 关于新增内容的说明 = | |||
如果你想要用Build 159(v159)或更高版本引入的系统添加新内容,这个系统和数据补丁(Content Patches)有些不同。 | |||
* | 目前还没有全面的指南,但这里简要介绍了它的运作方式: | ||
* | |||
* | 内容格式与JSON模组相同,但有一些'''限制'''。 | ||
* | '''不支持'''的功能: | ||
* 行星(在地图/服务器中无用) | |||
* 区块,原因相同 | |||
* 科技树的新增/修改 | |||
* 无法直接重新分配纹理区域;它们是根据内容名称加载的。 | |||
比如,你不能像用补丁那样设置方块。uiIcon: "cat" | |||
你需要把带有块名的图片作为素材加载。 | |||
例如,如果你有一个新块或物品叫“cat”,你需要在图片标签页导入“cat.png”,它会自动加载为方块的图标/精灵。 | |||
不同的方块有不同的图像命名方式,这可能相当复杂。这一点尚未有文献记录。 | |||
因为你定义的是新内容,而不是补丁,所以不支持字段选择器。 | |||
这包括尝试分配诸如:、、等。你一次只能直接分配到一个字段。weapons.0.nameweapons.+ | |||
* 所有素材和内容都带有前缀。dp- | |||
例如:如果你导入一个名为“cat-weapon”的PNG,精灵名称在纹理标记和武器名称中会是“dp-cat-weapon”。声音也是如此。 | |||
= 编写一个琐碎的数据补丁 = | |||
数据补丁用 JSON 或 HJSON(JSON 的超集)编写。你需要一个文本编辑器来写它们;目前游戏内没有补丁编辑器。 | |||
为了简洁起见,本指南只会展示如何在 HJSON 中编写补丁。 | |||
首先,创建一个名为 My Patch(我的补丁) 的文本文件,内容如下:mypatch.hjson | |||
//为补丁命名是可选的,但这有助于在用户界面中识别它 | |||
name: My Patch | |||
//使所有传送带的最大生命值变为 50 | |||
block.conveyor.health: 50 | |||
= 应用数据补丁 = | |||
在地图上应用补丁 | |||
在地图编辑器中打开你的地图,然后打开左上角菜单(或在桌面端按ESC)。进入地图信息 -> 数据补丁 ->添加,然后指定你在上一步保存的补丁文件。你可以点击⚠️图标查看补丁产生的错误,或者用按钮🔁重新加载文件。 | |||
= 在专用服务器上应用补丁 = | |||
打开你的服务器目录(里面应该已经有插件、地图、存档等文件夹),找到目录,然后把你的补丁文件放进去。补丁文件必须带有扩展名才能加载。 在地图上已有的其他数据补丁之后,它们会自动应用到任何地图上。patcheshjson/json/json5 | |||
如果你操作正确,服务器应该会记录启动时加载的补丁文件数量。任何警告或错误也会印在主机上。 要在服务器仍在运行时重新加载补丁,请使用命令/reloadpatches。 | |||
= 数据补丁基础 = | |||
数据补丁遵循层级结构。在第一层,你定义要更改的内容类型:、等等。blockliquiditemunitweather | |||
在第二层,你定义要编辑内容的名称,例如,, , , 。这些名称区分大小写,如果你启用了控制台,会在核心数据库中显示在内容名称下方。conveyorcoppercopper-wall-large | |||
第三层,你定义你要更改的属性及其对应的值。举个例子: | |||
block: { | |||
conveyor: { | |||
health: 50 | |||
//此处列出输送机的其他特性…… | |||
} | |||
//此处为其他方块…… | |||
} | |||
//此处包含其他类型的内容…… | |||
或者,如果你只修改单一属性,使用简写语法可能更方便: | |||
block.conveyor.health: 50 | |||
查看所有字段内容 | |||
如果你熟悉 Java,可以查看相关的内容源文件,例如块的 Block.java。 | |||
如果没有,你可以在游戏设置中启用控制台,然后点击数据库中针对特定方块、单位或液体的“查看内容字段”按钮。 | |||
注意,这只会显示该特定类的字段——如果你想看到该超类的字段,请点击该页面“extends”后面的链接。 | |||
例如,Conveyors 会显示所有字段,以及 Block 超类中的所有字段。 | |||
访问数组/序列 | |||
当需要访问数组(T[])或序列(Seq)时,你可以这样做: | |||
//极大地抵消了尖刀两件武器中的一件 | |||
unit.dagger.weapons.0.x: 100 | |||
注意,修改镜面武器的子弹会影响双方,因为它们使用相同的子弹类型: | |||
//this wall make *both* dagger weapons deal 55 damage | |||
unit.dagger.weapons.0.bullet.damage: 55 | |||
添加与覆盖到数组/序列的区别 | |||
有时,可能需要对序列进行添加,而不是覆盖,比如这样: | |||
//adds a ridiculously overpowered laser to flare's weapons, keeping the others intact | |||
//note the .+ before the field assignment; this adds the element | |||
//also note that it can be a single element, not an array! | |||
unit.flare.weapons.+: { | |||
x: 0 | |||
y: 0 | |||
reload: 10 | |||
bullet: { | |||
type: LaserBulletType | |||
damage: 100 | |||
} | |||
} | |||
或者,你也可以覆盖数组: | |||
//flare will *only* have this weapon now, its old ones will be overwritten | |||
//also note that, when overwriting, you *have* to use the array brackets [], since you are assigning a new value | |||
unit.flare.weapons: [ | |||
{ | |||
x: 0 | |||
y: 0 | |||
reload: 10 | |||
bullet: { | |||
type: LaserBulletType | |||
damage: 100 | |||
} | |||
} | |||
] | |||
该语法适用于类型为 、 和 的字段。T[]Seq<T>ObjectSet | |||
一般信息 | |||
时间值通常以刻(有时称为“帧”)来衡量,即1/60秒(60秒=1秒)。如果一个字段描述了一个时长,通常以刻数为单位。如果一个字段描述了消耗速率,通常以“每刻单位”表示。 | |||
距离、位置和大小通常以“世界单位”衡量,世界单位为1/8格子。这是因为Mindustry以前有8x8的精灵,而一个世界单元以前是1像素。这很糟糕且不直观,但出于历史原因仍然存在。 | |||
当你通过逻辑处理器与坐标交互时,坐标会在内部与世界单位之间转换。补丁直接修改场地,没有这种奢华。 | |||
物品和液体堆叠可以定义为“名称/数量”。例如,一个字段的值可以为。ItemStackthorium/100 | |||
注意事项与限制 | |||
创建或分配单位武器无法使用,因为初始化不会为单位重跑。你需要手动创建一个镜像版本并分配 。mirror: truex/shootX/flipSprite | |||
即使你增加单位子弹的寿命或速度,也不会更新。这些数值必须手动分配。rangemaxRange | |||
同样,单位字段如果重新分配类型也不会更新。例如,重新分配的海军单位仍然会溺水。 | |||
clipSize即使你让它们画更大的精灵,也不会更新方块或单位。手动分配。 | |||
许多消费型类型无法支持未设计支持它们的模块。一般来说,如果原版没用到,说明支持不好。 | |||
方块的大小无法重新分配,因为那样会严重破坏存档,而且对大多数运输方块来说完全无法使用。 | |||
依赖于其他值的值不会被重新分配。比如,改变某个方块的物品建造需求不会像模组那样改变它的建造时间。 | |||
环境(静态)方块不能使用环境图集页面之外的纹理。换句话说,你可以让草地使用雪地精灵,但不能让草地使用路由器精灵;游戏内会显示错误纹理。 | |||
贴图在补丁应用后不会重新加载。例如,如果你更改 的 或 ,它不会有任何反应,因为不会再次调用。而是创建一个全新的对象。suffixnameDrawRegionload | |||
重新分配单位/方块的生命值不会更新任何现有单位/方块当前的健康值。如果你提高一个方块的最大生命值,地图上该类型的建筑都会显示为受损。 | |||
补丁很可能会崩溃或冻结游戏。如果发生了请报告,但请记住我可能无法解决所有问题——请保持合理。关于“我让这个单位生成了9万亿发子弹,结果游戏卡死了”的bug报告将被忽略。 | |||
额外示例 | |||
“双重化” | |||
//once again, names are optional, but help identify a patchset in the list | |||
name: Duofication | |||
item: { | |||
//fissile-matter is an unused item, so use it for demonstration | |||
fissile-matter: { | |||
//change the display name of the item to 'Duo' | |||
localizedName: Duo | |||
//unhide it | |||
hidden: false | |||
//change the in-game icon to 'duo-preview', which is used by the duo turret | |||
fullIcon: duo-preview | |||
//change the in-ui icon to 'block-duo-ui', which is also used by the duo turret in UI | |||
uiIcon: block-duo-ui | |||
} | |||
} | |||
block: { | |||
//edit the pulverizer | |||
pulverizer: { | |||
//change its name | |||
localizedName: Duo Factory | |||
//rewrite the things it consumes | |||
consumes: { | |||
//remove all previous consumers - without this line, it would retain its old consumption of scrap | |||
//you can also remove *only* item consumers by writing `remove: items` | |||
remove: all | |||
//consume 1 copper item per craft | |||
item: copper | |||
} | |||
//change the UI display icon | |||
uiIcon: block-duo-ui | |||
//change the region | |||
region: block-duo-full | |||
//output 1 fissile matter, which was previously patched to have the name 'Duo' | |||
//note that outputItems is an array, so its contents have to be written as a list with [ and ] | |||
outputItems: [fissile-matter/1] | |||
//define the drawers, which define how the block is rendered. they can be defined as an array with [] | |||
drawer: [ | |||
{ | |||
//the first drawer is a simple DrawRegion, which draws the sprite 'block-1', which is the base for 1x1 Serpulo turrets | |||
type: DrawRegion | |||
name: block-1 | |||
} | |||
{ | |||
//the second drawer draws the 'duo-preview' region and rotates it at speed 1 | |||
type: DrawRegion | |||
rotateSpeed: 1 | |||
name: duo-preview | |||
} | |||
] | |||
} | |||
} | |||
unit: { | |||
//patch the dagger unit | |||
dagger: { | |||
//change its body region to duo-preview | |||
region: duo-preview | |||
//re-define the weapon array (note: this clears all previous weapons) | |||
weapons: [ | |||
//all weapons in the array are objects of their own, so they need to be encased in {} braces | |||
{ | |||
//the weapon is centered on the unit | |||
x: 0 | |||
y: 0 | |||
//reload of 20 ticks (1 second = 60 ticks) | |||
reload: 20 | |||
//alternate left and right with a spread of 3.5 world units (1 tile = 8 world units) | |||
shoot: { | |||
type: ShootAlternate | |||
spread: 3.5 | |||
} | |||
//define the bullet the weapon shoots | |||
bullet: { | |||
//width and height of the sprite in world units | |||
width: 7 | |||
height: 9 | |||
//lifetime in ticks (1 second) | |||
lifetime: 60 | |||
//colors of the bullet as a hex code | |||
frontColor: eac1a8 | |||
backColor: d39169 | |||
} | |||
} | |||
] | |||
} | |||
} | |||
改装炮塔弹药 | |||
block.fuse.ammoTypes: { | |||
//remove titanium ammo from the ammo map by using the special "-" value | |||
titanium: "-" | |||
//add surge alloy ammo that shoots a laser | |||
surge-alloy: { | |||
type: LaserBulletType | |||
//make it produce 1 shot per ammo item | |||
ammoMultiplier: 1 | |||
//make it shoot half as fast | |||
reloadMultiplier: 0.5 | |||
damage: 100 | |||
//make it look awful! | |||
colors: ["000000", "ff0000", "ffffff"] | |||
} | |||
} | |||
添加单位能力 | |||
//add a new ability to pulsar (note the .+) | |||
unit.pulsar.abilities.+: [ | |||
{ | |||
type: ForceFieldAbility | |||
//set the maximum health of of the force field to 1000 | |||
max: 1000 | |||
} | |||
] | |||
添加单元平面图 | |||
//make the ground factory produce flares | |||
block.ground-factory.plans.+: { | |||
unit: flare | |||
//require 10 surge alloy to build | |||
requirements: [surge-alloy/10] | |||
//take 100 ticks to build | |||
time: 100 | |||
} | |||
修改单元工厂平面图 | |||
//make daggers (the first plan of the ground factory, or index 0) take 60 ticks to build, or 1 second | |||
block.ground-factory.plans.0.time: 60 | |||
修改区块要求 | |||
//make duo cost 5 titanium and 20 surge alloy | |||
block.duo.requirements: [titanium/5, surge-alloy/20] | |||
= 写一个简单的数据补丁 = | = 写一个简单的数据补丁 = | ||
2026年8月17日 (一) 18:49的最新版本
数据补丁
数据补丁(Data Patches,旧称数据补丁,Content Patches,于v159更名)是一种强大的工具,可以针对每个地图或服务器修改方块、单位和物品的属性。该功能的应用包括平衡补丁、自定义游戏模式或不同的游戏进程。
数据补丁'可以做到:
- 增加或减少工厂的输入;
- 改变方块的建造需求;
- 完全改变某单位的武器和子弹;
- 改变单位工厂的配方;
- 把方块或单位的贴图改成游戏内其他纹理;
- 改变任意方块的建造速度、生命值、或装甲等等;
- 改变单位的类型,如从陆军变为空军。
- 向游戏中添加新纹理或资源文件;
- 添加新内容,如方块、单位等;
数据补丁无法做到:
- 添加原版没有的新机制;(译者注:JSON模组只能根据原版已有的架构进行编辑,因此数据补丁同理)
- 改变方块的类型,如把墙变成炮塔;(译者注:原因如上)
尽管平衡补丁有着堪比JSON模组的能力,但它仍然不是模组的替代器(译者注:指一般性的内容模组)(尤其是JAVA模组)
关于新增内容的说明
如果你想要用Build 159(v159)或更高版本引入的系统添加新内容,这个系统和数据补丁(Content Patches)有些不同。
目前还没有全面的指南,但这里简要介绍了它的运作方式:
内容格式与JSON模组相同,但有一些限制。 不支持的功能:
- 行星(在地图/服务器中无用)
- 区块,原因相同
- 科技树的新增/修改
- 无法直接重新分配纹理区域;它们是根据内容名称加载的。
比如,你不能像用补丁那样设置方块。uiIcon: "cat" 你需要把带有块名的图片作为素材加载。 例如,如果你有一个新块或物品叫“cat”,你需要在图片标签页导入“cat.png”,它会自动加载为方块的图标/精灵。 不同的方块有不同的图像命名方式,这可能相当复杂。这一点尚未有文献记录。 因为你定义的是新内容,而不是补丁,所以不支持字段选择器。 这包括尝试分配诸如:、、等。你一次只能直接分配到一个字段。weapons.0.nameweapons.+
- 所有素材和内容都带有前缀。dp-
例如:如果你导入一个名为“cat-weapon”的PNG,精灵名称在纹理标记和武器名称中会是“dp-cat-weapon”。声音也是如此。
编写一个琐碎的数据补丁
数据补丁用 JSON 或 HJSON(JSON 的超集)编写。你需要一个文本编辑器来写它们;目前游戏内没有补丁编辑器。
为了简洁起见,本指南只会展示如何在 HJSON 中编写补丁。
首先,创建一个名为 My Patch(我的补丁) 的文本文件,内容如下:mypatch.hjson
//为补丁命名是可选的,但这有助于在用户界面中识别它
name: My Patch
//使所有传送带的最大生命值变为 50 block.conveyor.health: 50
应用数据补丁
在地图上应用补丁 在地图编辑器中打开你的地图,然后打开左上角菜单(或在桌面端按ESC)。进入地图信息 -> 数据补丁 ->添加,然后指定你在上一步保存的补丁文件。你可以点击⚠️图标查看补丁产生的错误,或者用按钮🔁重新加载文件。
在专用服务器上应用补丁
打开你的服务器目录(里面应该已经有插件、地图、存档等文件夹),找到目录,然后把你的补丁文件放进去。补丁文件必须带有扩展名才能加载。 在地图上已有的其他数据补丁之后,它们会自动应用到任何地图上。patcheshjson/json/json5
如果你操作正确,服务器应该会记录启动时加载的补丁文件数量。任何警告或错误也会印在主机上。 要在服务器仍在运行时重新加载补丁,请使用命令/reloadpatches。
数据补丁基础
数据补丁遵循层级结构。在第一层,你定义要更改的内容类型:、等等。blockliquiditemunitweather
在第二层,你定义要编辑内容的名称,例如,, , , 。这些名称区分大小写,如果你启用了控制台,会在核心数据库中显示在内容名称下方。conveyorcoppercopper-wall-large
第三层,你定义你要更改的属性及其对应的值。举个例子:
block: {
conveyor: {
health: 50
//此处列出输送机的其他特性……
}
//此处为其他方块……
} //此处包含其他类型的内容……
或者,如果你只修改单一属性,使用简写语法可能更方便:
block.conveyor.health: 50
查看所有字段内容
如果你熟悉 Java,可以查看相关的内容源文件,例如块的 Block.java。
如果没有,你可以在游戏设置中启用控制台,然后点击数据库中针对特定方块、单位或液体的“查看内容字段”按钮。
注意,这只会显示该特定类的字段——如果你想看到该超类的字段,请点击该页面“extends”后面的链接。
例如,Conveyors 会显示所有字段,以及 Block 超类中的所有字段。
访问数组/序列 当需要访问数组(T[])或序列(Seq)时,你可以这样做:
//极大地抵消了尖刀两件武器中的一件
unit.dagger.weapons.0.x: 100
注意,修改镜面武器的子弹会影响双方,因为它们使用相同的子弹类型:
//this wall make *both* dagger weapons deal 55 damage
unit.dagger.weapons.0.bullet.damage: 55
添加与覆盖到数组/序列的区别
有时,可能需要对序列进行添加,而不是覆盖,比如这样:
//adds a ridiculously overpowered laser to flare's weapons, keeping the others intact
//note the .+ before the field assignment; this adds the element
//also note that it can be a single element, not an array!
unit.flare.weapons.+: {
x: 0
y: 0
reload: 10
bullet: {
type: LaserBulletType
damage: 100
}
} 或者,你也可以覆盖数组:
//flare will *only* have this weapon now, its old ones will be overwritten
//also note that, when overwriting, you *have* to use the array brackets [], since you are assigning a new value
unit.flare.weapons: [
{
x: 0
y: 0
reload: 10
bullet: {
type: LaserBulletType
damage: 100
}
}
] 该语法适用于类型为 、 和 的字段。T[]Seq<T>ObjectSet
一般信息 时间值通常以刻(有时称为“帧”)来衡量,即1/60秒(60秒=1秒)。如果一个字段描述了一个时长,通常以刻数为单位。如果一个字段描述了消耗速率,通常以“每刻单位”表示。 距离、位置和大小通常以“世界单位”衡量,世界单位为1/8格子。这是因为Mindustry以前有8x8的精灵,而一个世界单元以前是1像素。这很糟糕且不直观,但出于历史原因仍然存在。 当你通过逻辑处理器与坐标交互时,坐标会在内部与世界单位之间转换。补丁直接修改场地,没有这种奢华。 物品和液体堆叠可以定义为“名称/数量”。例如,一个字段的值可以为。ItemStackthorium/100 注意事项与限制 创建或分配单位武器无法使用,因为初始化不会为单位重跑。你需要手动创建一个镜像版本并分配 。mirror: truex/shootX/flipSprite 即使你增加单位子弹的寿命或速度,也不会更新。这些数值必须手动分配。rangemaxRange 同样,单位字段如果重新分配类型也不会更新。例如,重新分配的海军单位仍然会溺水。 clipSize即使你让它们画更大的精灵,也不会更新方块或单位。手动分配。 许多消费型类型无法支持未设计支持它们的模块。一般来说,如果原版没用到,说明支持不好。 方块的大小无法重新分配,因为那样会严重破坏存档,而且对大多数运输方块来说完全无法使用。 依赖于其他值的值不会被重新分配。比如,改变某个方块的物品建造需求不会像模组那样改变它的建造时间。 环境(静态)方块不能使用环境图集页面之外的纹理。换句话说,你可以让草地使用雪地精灵,但不能让草地使用路由器精灵;游戏内会显示错误纹理。 贴图在补丁应用后不会重新加载。例如,如果你更改 的 或 ,它不会有任何反应,因为不会再次调用。而是创建一个全新的对象。suffixnameDrawRegionload 重新分配单位/方块的生命值不会更新任何现有单位/方块当前的健康值。如果你提高一个方块的最大生命值,地图上该类型的建筑都会显示为受损。 补丁很可能会崩溃或冻结游戏。如果发生了请报告,但请记住我可能无法解决所有问题——请保持合理。关于“我让这个单位生成了9万亿发子弹,结果游戏卡死了”的bug报告将被忽略。 额外示例 “双重化”
//once again, names are optional, but help identify a patchset in the list name: Duofication
item: {
//fissile-matter is an unused item, so use it for demonstration
fissile-matter: {
//change the display name of the item to 'Duo'
localizedName: Duo
//unhide it
hidden: false
//change the in-game icon to 'duo-preview', which is used by the duo turret
fullIcon: duo-preview
//change the in-ui icon to 'block-duo-ui', which is also used by the duo turret in UI
uiIcon: block-duo-ui
}
}
block: {
//edit the pulverizer
pulverizer: {
//change its name
localizedName: Duo Factory
//rewrite the things it consumes
consumes: {
//remove all previous consumers - without this line, it would retain its old consumption of scrap
//you can also remove *only* item consumers by writing `remove: items`
remove: all
//consume 1 copper item per craft
item: copper
}
//change the UI display icon
uiIcon: block-duo-ui
//change the region
region: block-duo-full
//output 1 fissile matter, which was previously patched to have the name 'Duo'
//note that outputItems is an array, so its contents have to be written as a list with [ and ]
outputItems: [fissile-matter/1]
//define the drawers, which define how the block is rendered. they can be defined as an array with []
drawer: [
{
//the first drawer is a simple DrawRegion, which draws the sprite 'block-1', which is the base for 1x1 Serpulo turrets
type: DrawRegion
name: block-1
}
{
//the second drawer draws the 'duo-preview' region and rotates it at speed 1
type: DrawRegion
rotateSpeed: 1
name: duo-preview
}
]
}
}
unit: {
//patch the dagger unit
dagger: {
//change its body region to duo-preview
region: duo-preview
//re-define the weapon array (note: this clears all previous weapons)
weapons: [
//all weapons in the array are objects of their own, so they need to be encased in {} braces
{
//the weapon is centered on the unit
x: 0
y: 0
//reload of 20 ticks (1 second = 60 ticks)
reload: 20
//alternate left and right with a spread of 3.5 world units (1 tile = 8 world units)
shoot: {
type: ShootAlternate
spread: 3.5
}
//define the bullet the weapon shoots
bullet: {
//width and height of the sprite in world units
width: 7
height: 9
//lifetime in ticks (1 second)
lifetime: 60
//colors of the bullet as a hex code
frontColor: eac1a8
backColor: d39169
}
}
]
}
} 改装炮塔弹药
block.fuse.ammoTypes: {
//remove titanium ammo from the ammo map by using the special "-" value
titanium: "-"
//add surge alloy ammo that shoots a laser
surge-alloy: {
type: LaserBulletType
//make it produce 1 shot per ammo item
ammoMultiplier: 1
//make it shoot half as fast
reloadMultiplier: 0.5
damage: 100
//make it look awful!
colors: ["000000", "ff0000", "ffffff"]
}
} 添加单位能力
//add a new ability to pulsar (note the .+) unit.pulsar.abilities.+: [
{
type: ForceFieldAbility
//set the maximum health of of the force field to 1000
max: 1000
}
] 添加单元平面图
//make the ground factory produce flares block.ground-factory.plans.+: {
unit: flare //require 10 surge alloy to build requirements: [surge-alloy/10] //take 100 ticks to build time: 100
} 修改单元工厂平面图
//make daggers (the first plan of the ground factory, or index 0) take 60 ticks to build, or 1 second block.ground-factory.plans.0.time: 60 修改区块要求
//make duo cost 5 titanium and 20 surge alloy block.duo.requirements: [titanium/5, surge-alloy/20]
写一个简单的数据补丁
数据补丁通常是使用JSON或HJSON语言(JSON的超集)所写的。你需要一个文本编辑器,因为暂时还没有游戏内的编辑器。(译者注,此处可参见JSON模组教程-模组开发基础了解更多)。
出于简洁的理由,本教程只会展示如何使用HJSON写数据补丁;
首先,创造一个文本文件,名为mypatch.hjson,填入以下内容:
//命名是可有可无的,但是有名称利于在UI中管理 name: My Patch //使“传送带”最大生命值变为50 block.conveyor.health: 50
应用数据补丁
在地图中应用
打开地图编辑器,然后打开左上方的菜单键(在桌面端按下ESC),转到 * 地图信息(Map Info) -> 数据补丁(Data Patches) -> 添加(Add)* ,然后填入上一步保存的文件。按下⚠️ 可以看到产生的所有错误,按下🔁可以重新加载文件。
在服务器上应用
打开服务器文件夹(里面有plugins/ maps/ saves/之类的文件夹),找到patches/文件夹,把文件放在里面。数据文件必须是hjson/json/json5拓展名才能被加载。这些数据补丁将会在地图补丁之后被应用。(译者注:意在强调服务器补丁优先级高于地图补丁)
如果以上步骤无误,服务器会输出启动后加载补丁的日志。错误和警告会打印到控制台中。如果想到重新加载补丁,需要使用reloadpatches命令。
数据补丁基础
数据补丁遵循一定的层次体系。在第一层中,你需要定义你想要更改的内容的类型,例如block、 liquid、 item、 unit、 weather等。
在第二层,你需要定义你想要更改的内容的内部名称,例如conveyor copper copper-wall-large。这些名称是大小写敏感的,并且这些名称会在核心数据库中在名称下显示出来(需要启用控制台)。(译者注,可参考JSON模组教程-物品与流体了解更多与内部名称有关的内容。)
在第三层,你需要定义你想要更改的属性,和相应的值。例如:
block: {
conveyor: {
health: 50
//传送带的其他属性在此
}
//其他方块在此
}
//其他内容的内容在此
相应地,如果你更改一条属性,使用缩写语法会更快一些:
block.conveyor.health: 50
查看内容的所有字段
比较熟悉Java,你可以直接查阅源代码,比如直接查Block.java来获取方块共性的字段。
如果你不懂Java,你需要在游戏设置中启用控制台,然后点击某个方块或物品详细页的 查看内容字段(View Content Fields)
注意,这个页面只会显示本类定义的字段,它还有超类的字段,点击extends后的页面来访问超类的字段。
访问数组或列表
如果需要访问数组(形如T[],其中T指任何类型),或者是一个列表(形如Seq< T >),你可以这样做:
//极大地使尖刀的左炮偏移了原来的位置 unit.dagger.weapons.0.x: 100
注意,修改镜像武器的子弹会同时影响两侧武器,因为它们本来就共用同一个子弹:
//这会使两侧武器子弹伤害*均*为55 unit.dagger.weapons.0.bullet.damage: 55
添加或覆盖数组或列表
有时,我们需要向列表中添加内容,而不是覆盖它:
//给“星辉”加一下有趣的激光炮,而其它武器完好无损
//注意此处的.+,这是用来添加项目的
//也要注意,添加的是一个对象,而不能添加一数组对象!
unit.flare.weapons.+: {
x: 0
y: 0
reload: 10
bullet: {
type: LaserBulletType
damage: 100
}
}
相应地,你也可以覆盖列表:
//“星辉”现在只有这个炮塔了,原来的炮塔被覆盖了
//也要注意,因为是*覆盖*,所以你需要提供一整个数组,注意此处的[]
unit.flare.weapons: [
{
x: 0
y: 0
reload: 10
bullet: {
type: LaserBulletType
damage: 100
}
}
]
此语法可用于T[] Seq< T > ObjectSet。
通识
- 时间通常是使用刻衡量的,有时也叫做帧,是1/60秒,1秒=60刻。如果某个字段代表一段时长,很有可能是按刻计算的。如果一个字段代表速率,很有可能也是“每刻消耗量”;
- 距离、位置和尺寸通常是使用“世界单位”衡量的,一世界单位是1/8格。这是因为Mindustry过去每格贴图是8x8像素的,以前一世界单位确实是一像素。这很不符合直觉,但历史遗留已然如此;
- 逻辑处理器处理坐标时,在内部就有向世界单位的转换。但补丁是直接作用的,没有这个待遇;
- 物品和液体组可以写成
名称/数量的形式,例如,一个ItemStack可以是thorium/100.
警告与限制
- 给单位武器赋值
mirror: true并没有用。因为创建镜像武器是在单位初始化时做的,应用内容补丁并不会初始化单位。你需要手动做mirror的工作,比如自己镜像x/shootX/flipSprite; - 单位的
range和maxRange不会自动更新,即使你设置lifetime和speed提高了武器子弹的射程。你需要手动更新; - 类似地,单位更改了类型后,字段也不会自动赋值,比如把尖刀变成海军默认仍然会被淹死;
- 方块和单位的
clipSize也不会更新,即使你扩大了它们的渲染范围。手动赋值之; - 很多消耗器在不支持的方块上不会工作。通常来说,如果原版没有类似设计,则可能支持不会很好;
- 不可重新设置方块的尺寸,否则会崩溃存档。并且大部分物流方块变大并没有意义;
- 有依赖关系的值统统不会自动重设。例如,更改方块的建筑需要并不会更新它的建造时间;(译者注:原版方块建造时间是根据需要物品算出来的,而不是自己设置的)
- 环境静态方块不可使用非环境页的纹理。换而言之,你可以让草地使用雪地的贴图,但是不能使用路由器的贴图,否则会显示错误;(译者注:根据渲染时如何更新,原版贴图分为五个页表,分别为
mainenvironmenteditoruirubble,在不同渲染阶段只能使用一张页表。所以渲染环境方块的时候不能使用主页表里的贴图,反之也不可以) - 应用补丁后不会加载贴图。例如,你修改了
DrawRegion的name·,会没有任何效果,因为游戏不会再加载贴图了; - 提高单位或方块的最大生命值不会提升已有实体的生命值,但降低确实可以立即造成伤害;
- 补丁很有可能会炸端或卡死。如果发生请立即报告,但要记住我不会什么都修的——别太离谱,像是说“我生成了九十亿的子弹然后游戏卡死了”。
其他例子
‘双管生万物’
//再说一遍,命名可有可无,但方便在补丁页面查看
name: Duofication
item: {
//“裂变产物是个没有用的物品,所以用它作演示
fissile-matter: {
//把显示名字改成Duo
localizedName: Duo
//取消它的隐藏
hidden: false
//把游戏里围标改成'duo-preview',是双管使用的
fullIcon: duo-preview
//把UI图标改成'block-duo-ui',这也是双管使用的
uiIcon: block-duo-ui
}
}
block: {
//编辑“粉碎机”
pulverizer: {
//改名字
localizedName: Duo Factory
//重写消耗器
consumes: {
//删除先前所有消耗器,如果不写,还是会消耗废料
//你可以通过`remove: 某物品`来只删除某物品(译者注:此处不明是填字符串还是列表)
remove: all
//每次消耗一个铜
item: copper
}
//更改UI图标
uiIcon: block-duo-ui
//更改贴图
region: block-duo-full
//输出一个“裂变产物”虽然之前已经命名成Duo了
//注意outputItems是一个列表
outputItems: [fissile-matter/1]
//定义绘制器
drawer: [
{
//第一步就是简单的DrawRegion,画了一张'block-1'贴图,这是1x1炮塔的底座
type: DrawRegion
name: block-1
}
{
//再画一张速度为1旋转的'duo-preview'
type: DrawRegion
rotateSpeed: 1
name: duo-preview
}
]
}
}
unit: {
//修改“尖刀”
dagger: {
//把身体主体改成duo-preview
region: duo-preview
//重定义武器,这会删除所有原来的武器
weapons: [
//每个武器自己是一个对象,所以分别用{}括上
{
//武器居中
x: 0
y: 0
//CD为20刻,即1/3秒
reload: 20
//3.5世界单位长度间隔的两个炮管交替射击
shoot: {
type: ShootAlternate
spread: 3.5
}
//定义武器发射的子弹
bullet: {
//贴图的尺寸,仍然以世界单位计算
width: 7
height: 9
//子弹寿命,1秒
lifetime: 60
//子弹颜色,使用十六进制色
frontColor: eac1a8
backColor: d39169
}
}
]
}
}
修改炮塔子弹
block.fuse.ammoTypes: {
//移除此项,使用"-"
titanium: "-"
//添加发射激光的巨浪合金
surge-alloy: {
type: LaserBulletType
//每次射击消耗1物品
ammoMultiplier: 1
//CD减少一半
reloadMultiplier: 0.5
damage: 100
//让颜色看起来很吓人
colors: ["000000", "ff0000", "ffffff"]
}
}
添加单位能力
//给“恒星”添加新能力,注意.+
unit.pulsar.abilities.+: [
{
type: ForceFieldAbility
//盾量最大1000
max: 1000
}
]
添加单位计划
//让陆军工厂生产星辉
block.ground-factory.plans.+: {
unit: flare
//需要十个巨浪合金
requirements: [surge-alloy/10]
//需要100刻
time: 100
}
修改单位工厂配方
//让尖刀,也就是第一个配方(Java中从0开始数)的生产时间为1秒 block.ground-factory.plans.0.time: 60
修改方块造价
//让双管炮造价为5个钛和20个巨浪合金 block.duo.requirements: [titanium/5, surge-alloy/20]
