Skip to content

0x0A Java 语法初步与 ContentParser

“知其然,更知其所以然。”

我们已经学会了如何查阅源码并配置各种花哨的属性。但是,在 JSON 中填入的一行行数据,究竟是如何在游戏中变为真实运行的逻辑的?

本章,我们将简单窥探 Java 语法的面貌,并揭开 Mindustry 核心解析器——ContentParser 的神秘面纱。理解了它,你就能彻底明白为什么 JSON 里的格式必须那样写,以及 JSON 模组真正的边界在哪里。

学习本章需要具备的基础:

  • 已经阅读并掌握了 0x09 中查阅源码的方法。

Java 数据类型初窥

当你打开原版的 .java 文件时,你会看到类似这样的句子: public float reload = 60f;public boolean rotate = true;

这些前缀词被称为数据类型。了解它们,你就知道在 JSON 里该填什么格式:

  • int (整数):只能填整数。例如 size: 3
  • float (浮点数):可以填小数。在 Java 里后面带有 f(如 2.5f),但在 JSON 里绝对不要加 f,直接写 2.5
  • boolean (布尔值):只接受两个词:true (是) 或 false (否)。
  • String (字符串):表示一段文本。在 Java 里必须用双引号包围("Bang"),在 Hjson 里可以省去引号。
  • Color (颜色):在 Java 里是用十六进制数值表示的,在 JSON 里直接写六位或八位的十六进制码,如 ff0000
  • Seq / ObjectMap / []:代表数组或集合。在 JSON 里用方括号 [ ] 来表示。

伟大的翻译官:ContentParser

在 Mindustry 的源码中,有一个极为庞大且复杂的文件:core/src/mindustry/mod/ContentParser.java。 它就是处理所有 JSON 模组的“翻译官”。

它是如何工作的?

  1. 它读取你的 mod.json,发现有 content/ 文件夹。
  2. 它读取 content/blocks/ 下的文件,看到了 type: GenericCrafter
  3. 它通过 Java 反射 (Reflection) 机制,在内存中动态地实例化了一个 GenericCrafter 对象。
  4. 接着,它逐行读取你的 JSON。每读到一个键(例如 health: 500),它就会尝试去这个对象里找名为 health 的变量,然后把 500 塞进去。

为什么它可以识别缩写糖?

在之前,我们频繁使用了诸如 copper/10 这样的缩写,而不是老老实实写 {"item":"copper", "amount":10}。这并不是 JSON 本身的魔法,而是 ContentParser 的特殊关照!

如果去阅读 ContentParser.java 的源码,你会发现里面有很多针对特定类型的硬编码解析逻辑。 比如,当它尝试解析一个 ItemStack(物品堆叠要求)时,如果发现你传进来的是一个字符串(如 copper/10),它会主动/ 将其劈开,前面找物品(copper),后面转数字(10)。

类似的“语法糖”还包括:

  • StatusEffect:可以直接写名字,不需要写完整的对象。
  • 音效:自动补全文件路径。

JSON 的局限与进阶之路

现在我们明白了,JSON 模组的本质是调用原版预定义好的 Java 类,并给它们的变量赋新值

这就是为什么:

  • 你可以通过修改 speed 让子弹变快。
  • 你可以通过修改 damage 让炮塔伤害变高。

但是,你无法创造全新的逻辑! 如果我想做一把“子弹每飞行 1 秒就分裂一次,并且分裂出的子弹会追踪附近血量最低的友军进行治疗”的武器,你翻遍了所有原版的 BulletType,发现没有一个类有这种功能变量。 此时,ContentParser 也束手无策,因为它只能给已有的变量赋值,无法凭空创造方法 (Method)

这时候,你就触碰到了 JSON 模组的“天花板”。 像《饱和火力》这样的高级模组,为了实现前所未有的机制,它们在 mod.json 中声明了 java: true,抛弃了单纯的数据配置,直接编写 Java 源代码来覆盖、重写游戏的底层逻辑,甚至自己写一个属于自己的 BulletType

不要气馁,熟练掌握 JSON 模组是你理解游戏机制的最佳跳板。当你觉得自己不再满足于修改数值,而是渴望创造新的物理法则时,欢迎踏入更深邃的代码世界:学习 Javascript 脚本模组,甚至挑战终极的 Java 模组开发!

Mindustry JSON 基础开发指南 到此结束,愿你的工业帝国生生不息。