官方维基教程-模组制造介绍
模组制作介绍
Mindustry的模组只是由目录构成的,你可以用许多种方法调用模组API,具体做法取决于你要什么和你多深入地去写。
你可以重写现有的游戏内容,使用简单的 json 来创建新的内容——这也是本文章的重点。还可以添加自定义的音效,或使用已有的音效,还可以添加地图到自定义模式中,甚至加入脚本,比如添加自定义效果。
分享模组就像给别人项目目录一样简单,可以使用任何平台。你可以用像 Github 或者类似的服务托管你的代码。制作模组也只需要一个文本编辑器。
目录结构
你的模组目录结构应该与下面相仿:
项目 ├── mod.hjson ├── content │ ├── items │ ├── block │ ├── liquids │ └── units ├── maps ├── bundles ├── sounds ├── schematics ├── scripts ├── sprites-override └── sprites
- mod.hjson (必须) 是你模组的基础数据,
- content/ 目录是游戏内容,
- maps/ 目录是游戏内地图,
- bundles/ 目录是语言文件,
- sounds/ 目录是音效文件,
- schematics/ 目录是蓝图文件,
- scripts/ 目录是脚本文件,
- sprites-override/ 目录是覆盖原版的贴图文件,
- sprites/ 目录是模组内容的贴图文件
不同的平台的用户数据存放位置不同,下面列出的是模组存放的位置:
- Linux: ~/.local/share/Mindustry/mods/
- Steam: /steam/steamapps/common/Mindustry/mods/
- Windows: %appdata%/Mindustry/mods/
- MacOS: ~/Library/Application Support/Mindustry/mods/
注意,你的文件名应该全小写并且不能有空格:
- 正确的: my-custom-block.json
- 错误的: My Custom Block.json
Hjson
Mindustry 使用 Hjson,它是 Json 语言的一个非常流行的序列化超集。所以任何原版 Json 能做的事它都能做,并且能做的更多,所以有一些更有用的语法:
# 单行注释
// 单行注释
/* 多行
注释 */
key1: 单行字符串
key2:
'''
多行
字符串
'''
key3: [ 值 1
值 2
值 3 ]
key4: { key1: 字符串
key2: 0 }
如果你看不懂,你只需要知道 ——序列化语言是为程序编码设计的。 编码,就是把信息转化成另一种形式,在这里我们如此编码是为 Java 使用。
mod.hjson
在你项目文件夹的根目录下,你必须有一个名为 mod.json 的文件,它标记了你模组的基础数据。这个文件也可以被命名为 mod.hjson ,这样你的文本编辑器将能更好地处理高亮。
name: "mod-name"
displayName: "这不是一个模组。"
author: 你自己
description: "Bbfashbjhcbabfhsbafbhajbf"
version: "1.0"
minGameVersion: "135"
dependencies: [ ]
hidden: false
- name 名称将用于引用你的模组,所以请小心命名,只能包含英文数字符号;
- displayName 显示名称将用于在界面上显示你的模组的名字 ,你可以添加格式,并且支持任何 Unicode字符;
- description 描述会出现在游戏内模组管理器中,所以务必简明扼要;
- dependencies 依赖是可选项,查看下方dependence了解更多;
- minGameVersion 最低版本是模组可以被加载的最低版本,对于6.0来说最低不小于105;
- hidden 隐藏影响模组能否用于多人游戏,默认为 false,语言包,js 插件等不影响游戏内容的键值应为 true。对于有德的人,添加了内容的模组不应该 true。
内容
在项目目录的根目录下,可以建立一个 content 目录,这是所有Json/Hjson 数据所在地。下面是一些常用的子目录:
- content/items/ 用于物品,例如巨浪合金和铜;
- content/blocks/ 用于方块,例如炮塔和地板;
- content/liquids/ 用于液体,例如水和矿渣;
- content/units/ 用于空中或地面单位,例如日蚀和尖刀;
注意,每一个内容都需要一个独一无二的名称,它们文件名十分重要,因为文件名用于引用此内容。
此外,内容也可以在各自的文件夹内再嵌套文件夹,这方便于你组织内容。例如:
- content/items/metals/iron.hjson, 这也可以创建一个名为 iron 的物品
这些文件的内容通常如下所示:
type: 类型
name: 名称
description: 描述
# ... 以及更多的字段 ...
| 字段 | 类型 | 描述 |
|---|---|---|
| type | String | 这个对象的类型 |
| name | String | 内容的显示名称 |
| description | String | 内容的描述 |
包含的其他字段将是类型本身的字段。
另外,名称和描述在 json 中不是必须的,,你可以通过任何语言的 (Bundles)[#bundles]来定义 。然而,如果在语言文件中没有呈现,那么名字会变成 “.-.name,描述将变成空描述。
类型
类型中有许多字段,但最重要的还是类型,它是语义解析器一个重要的字段,用于声明对象的类型。路由器很显然不能用 Turret 炮塔类型,因为它们根本不是一种东西。
类可能会继承彼此,所以 MissileBulletType 中包含 BasicBulletType ,你可以在 MissileBulletType 类型中使用 BasicBulletType 的字段,例如 damage 伤害、lifetime 存活时间、speed 速度。字段是区分大小写的。
字段起的效果取决于特定的类型,一些类型不常用,通常它们都是其他类型的基础,比如 Block 。
在这个例子中,单位的类型是 flying 空军。炮的类型是 BulletType 炮塔类型,所以你可以使用 MissileBulletType 导弹炮塔 因为 BulletType类 继承于 MissileBulletType类。
单位也可以使用 mech , legs , naval 或者 payload 作为类型。
type: flying
weapons: [
{
bullet: {
type: MissileBulletType
damage: 9000
}
}
]
在 125.1 版本后,类型也可以是 Java 的类。
例如,定义一个方块类型为 MendProjector ,你必须写 type: mindustry.world.blocks.defense.MendProjector 而不是 type: MendProjector。
虽然对于 json 模组来说不是特别有用,但类型也可以从其他 Java 模组中获得。
研究
与类型平齐的还有一个字段,叫做 research 研究,可以把方块添加到科技书中。
research: duo
这将会在科技树上把你的方块添加到双管炮之后。如果想要添加到你模组的内容之后,直接写名字即可,使用其他模组内容才需要加上“模组名.”的前缀。
研究花费:
| 类型 | 花费 | 注释 |
|---|---|---|
| blocks | 需求 ** 1.1 * 20 * 研究花费倍率 | 研究花费倍率是方块的一个属性 |
| units | 需求 ** 1.1 * 50 |
然后根据成本的花费四舍五入到最接近的10倍、100倍、1k倍、10k倍或100k倍。
需求是方块/单位的成本。单位的成本是制造或者升级所需的物资。
如果要设置自定义研究要求,请使用对象代替字段,对象的写法如下:
research: {
parent: duo
requirements: [
copper/100
]
}
这个字段可以用来覆盖花费,也可以用来让某种资源仅用于研究而不用于制造。
贴图
所有人都得制作贴图。制作精灵图只需要一个支持透明度的图像编辑器(不是画板)。方块精灵图的大小应为 32*大小,因此 2x2 的方块需要 64x64的精灵图。图像必须是32位RGBA像素格式的PNG文件。任何其他像素格式,如16位RGBA,都可能导致Mindustry崩溃,并出现“Pixmap decode error”(Pixmap解码错误)。可以使用命令行工具打印精灵图的有关信息:
file sprites/**.png
如果其中任何一个不是32位RGBA格式,请修复它们。
贴图可以直接放在 sprites/或其子目录中。内容解析器将递归查看。图像会被打包到一个“图集”中,以便高效地渲染。sprites/中的第一个目录(例如sprites/blocks)决定了sprites所在的位置。在 units 页面中放置块精灵图可能会导致很多延迟;因此,你应该尝试像原版游戏那样组织。
内容将寻找与其自身名称相同的精灵图。 content/blocks/my-hail.json 和 sprites/my-hail.png 都有my-hail,所以就被成对使用。
内容也可能寻找多个贴图。假设 my-hail 是炮塔,它就可能寻找后缀为 -heat 的同名文件,这意味着它会找到 my-hail-heat文件。
你可以在[1]找到全部原版贴图。
还有一件事,有些精灵图会被游戏修改。例如炮塔上特别添加了黑色边框,所以在制作精灵时必须考虑到这一点,在炮塔周围留下透明的空间,例如:波浪。
要覆盖游戏内精灵图。你可以添加同名文件于 sprites-override/ 。这删除了它们id中的“模组名-”,可以覆盖原版甚至其他模组的精灵图。你也可以用简单的名字创建在此创建精灵图,然后在脚本中就可以简单地调用,不过要小心重名。
音效
自定义声音可以通过模组添加,方法是添加到 sounds/ 文件夹里,再进行子目录嵌套都没问题。支持两种格式:ogg和mp3,注意mp3不能呢泃无缝循环,所以要尽可能地使用ogg。//但ios只能读取mp3。//
正如其他内容一样,声音靠文件名引用,所以 pewpew.ogg 和 pewpew.mp3 能代表pewpew座位音效字段值。
这是内建音效的列表:
acceleratorCharge acceleratorConstruct acceleratorLaunch acceleratorLightning1 acceleratorLightning2 beamHeal beamLustre beamMeltdown beamParallax beamPlasma beamPlasmaSmall blockBreak1 blockBreak2 blockBreak3 blockExplode1 blockExplode1Alt blockExplode2 blockExplode2Alt blockExplode3 blockExplodeElectric blockExplodeElectricBig blockExplodeExplosive blockExplodeExplosiveAlt blockExplodeFlammable blockExplodeWall blockHeal blockPlace1 blockPlace2 blockPlace3 blockRepair blockRotate chargeCorvus chargeLancer chargeVela click coreLand coreLaunch door drillCharge drillImpact explosion explosionAfflict explosionArtillery explosionArtilleryShock explosionArtilleryShockBig explosionCleroi explosionCore explosionCrawler explosionDull explosionMissile explosionNavanax explosionObviate explosionPlasmaSmall explosionQuad explosionReactor explosionReactor2 explosionReactorNeoplasm explosionTitan healWave loopBio loopBuild loopCircuit loopCombustion loopConveyor loopCultivator loopCutter loopDifferential loopDrill loopElectricHum loopExtract loopFire loopFlux loopGlow loopGrind loopHover loopHover2 loopHum loopMachine loopMachine2 loopMachineSpin loopMalign loopMineBeam loopMissileTrail loopPulse loopRegen loopShield loopSmelter loopSpray loopSteam loopTech loopThoriumReactor loopThruster loopUnitBuilding massdriver massdriverReceive mechStep mechStepHeavy mechStepSmall padLand padLaunch plantBreak rain rockBreak shieldBreak shieldBreakSmall shieldHit shieldWave shipMove shipMoveBig shockBullet shockwaveTower shoot shootAfflict shootAlpha shootArc shootArtillery shootArtillerySap shootArtillerySapBig shootArtillerySmall shootAtrax shootAvert shootBeamPlasma shootBeamPlasmaSmall shootBreach shootBreachCarbide shootCleroi shootCollaris shootConquer shootCorvus shootCyclone shootDiffuse shootDisperse shootDuo shootEclipse shootElude shootEnergyField shootFlame shootFlamePlasma shootForeshadow shootFuse shootHorizon shootLancer shootLaser shootLocus shootMalign shootMeltdown shootMerui shootMissile shootMissileLarge shootMissileLong shootMissilePlasma shootMissilePlasmaShort shootMissileShort shootMissileSmall shootNavanax shootOmura shootPayload shootPulsar shootQuad shootReign shootRetusa shootRipple shootSalvo shootSap shootScathe shootScatter shootScepter shootScepterSecondary shootSegment shootSmite shootSpectre shootStell shootSublimate shootTank shootToxopidShotgun stepMud stepWater tankMove tankMoveHeavy tankMoveSmall uiBack uiButton uiChat uiFavorite uiNotify uiUnlock unitCreate unitCreateBig unitExplode1 unitExplode2 unitExplode3 walkerStep walkerStepSmall walkerStepTiny waveSpawn wind wind2 wind3 windHowl wreckFall wreckFallBig none unset
依赖
你可以通过简单地在你的 mod.json 中添加其他模组名称来为你模组添加依赖项。
dependencies: [
other-mod-name
not-a-mod
]
依赖项的名称是小写的,并且空格由 - 替代,比如 Other MOD NamE 变成 other-mod-name。
要引用其他mods资源,必须在资源前面加上其他mods名称:
other-mod-name-not-copper 将引用在 other-mod-name 的 not-copper other-mod-name-angry-dagger 将引用在 other-mod-name 的 angry-dagger not-a-mod-angry-dagger 将引用在 not-a-mod 的 angry-dagger
语言
一个可选的附加内容叫做 bundles 。bundles 的主要用途是提供内容的翻译,但在纯英语/汉语也未尝不可//__文言未死__//。它们应该放在bundle/ 中,并且格式为".properties”的纯文本文件。例如,标记为俄语时,它们应该被命名为 bundle_ru.properties 之类的名称。
该文件的内容非常简单:
block.example-mod-silver-wall.name = Серебряная Стена
block.example-mod-silver-wall.description = Стена из серебра.
如果你已经阅读了本指南的前几节,你会马上发现公式:
<类型名>.<模组名>-<内容名>.name <类型名>.<模组名>-<内容名>.description
用于脚本中时,您可以使用任意名称自定义 bundle 行:
message.egg = Eat your eggs
randomline = Random Line
注意:mod/content名称用小写字母和连字符分隔。 类型列表:
item block bullet liquid status unit weather sector error planet
可用的语言代码之表:
en pt_PT bg zh_TW in_ID cs vi es pl lt it hu pt_BR et nl ja nl_BE ro zh_CN fi eu tr ko th sr be fil tk sv uk_UA de da ru fr
GitHub
一旦你有了一个好玩的mod,你就会想要真正地分享它,你甚至可能想和其他人一起使用它,而要做到这一点,你可以使用GitHub。如果您根本不知道什么是Git(或GitHub),那么您应该查看GitHub Desktop,否则只需使用您最喜欢的命令行工具或文本编辑器插件即可。
您需要了解的只是如何在GitHub上打开存储库,在本地存储库中转移和提交更改,以及将更改推送到GitHub存储库。一旦你的项目在GitHub上,有三种方式可以共享它:
使用引用点。例如 Anuken/MindustryJavaModTemplate,这将使其展示于Github,可以随意下载;
使用压缩文件,例如 https://github.com/Anuken/MindustryJavaModTemplate/archive/master.zip 这将把模组下载为压缩文档,然后游戏内加载为模组即可;
在你的项目里添加 mindustry-mod 标签,这样它就会显示于游戏内模组浏览器。
常见问题
- 游戏内时间按刻(ticks)计算;
- 有时刻也叫 frame ,在游戏内假定通常等于 1/60 秒;
- 平铺显示是八个单位一组;(意味深
- 要计算寿命范围和速度,可以计算寿命*速度=范围;
- 什么是抽象类型?你无需知晓太多,但记住它们不能自行实例化/初始化,否则会出现初始化异常;
- 什么是NullPointerException?这是一条错误消息,指示不应为null的字段为null,这意味着可能缺少一个必需的字段;
- 什么是 bleeding-edge?这是Mindustry的开发者版本,特别是指Github主分支。 bleeding-edge 的变化通常会在下一个版本中进入Mindustry。
