Skip to content

0x0C 突破极限:过渡到 Javascript 与 Java

“从规则的遵守者,走向法则的创造者。”

在前面的章节中,我们已经将 JSON(Hjson)的潜力挖掘到了极致。我们配置了惊天动地的炮塔、设计了绚丽的多层光影特效,也构建了复杂的单位与工厂。 但是,如果你细心观察原版游戏,或是游玩了像《饱和火力》这样的大型高质量模组,你一定会遇到纯 JSON 无法解决的瓶颈。


1. JSON 的尽头在哪里?

JSON 本质上只是静态的数据单。正如在 0x0A 章节中提到的,游戏底层的 ContentParser 只能读取你写下的数据,然后把它填入原版已经存在的 Java 类属性中。

当你遇到以下脑洞大开的需求时,JSON 将无能为力:

  1. 全新的方块逻辑:我想做一个“每次开火都需要抽取并消耗周围友军血量”的黑暗献祭炮塔。
  2. 复杂的单位 AI:我想让我的无人机在血量低于 30% 时,停止攻击并自动隐身逃回母座修理。
  3. 环境与状态的动态化学交互:我想让单位身上的“燃烧”状态遇到地图上的“泄漏原油”方块时,引发大范围连锁爆炸。

面对这些需求,你必须跨出修改参数的舒适区,学习编写真正的逻辑代码


2. Javascript:轻巧灵活的过渡桥梁

Mindustry 底层内置了 Rhino 引擎,允许你在模组中直接运行 Javascript (JS) 脚本。 JS 脚本通常放在模组根目录的 scripts/ 文件夹下。它的最大优势在于不需要复杂的编译环境,你只需要像写 JSON 一样新建一个 .js 文件,写下代码,进入游戏就能立刻看到效果。

以《饱和火力》为例,当我们解包它的 scripts/mainSF.js 时,我们看到了这样惊艳的代码:

javascript
// 引入外部基础的 JS 定义文件
const SFStatusEffects = require("base/status");
require("units/ita"); // 动态加载特种单位“伊塔”

// 给原版的“燃烧(burning)”状态添加特殊联动逻辑
StatusEffects.burning.init(()=>{
    // 动态获取 Java 库中的类(此处调用了模组自己写的底层 Java 代码)
    let class1 = getClass("sf.lib.StatusLib");
    
    // 当“燃烧”遇到“焦油(tarred)”状态时,产生化学反应!
    class1.affinity(StatusEffects.burning, StatusEffects.tarred, (unit, result, time)=>{
        unit.damagePierce(8); // 造成额外的真实穿甲伤害
        Fx.burning.at(unit.x, unit.y); // 在单位身上实时生成燃烧特效
        result.set(StatusEffects.burning, Math.min(time + result.time, 300));
    });
});

在这个例子中,开发者使用 JS 监听并重写了原版状态效果的逻辑! JS 模组的定位:它非常适合用来写一些“边角逻辑”、修改现有单位的局部行为、或者为你的 JSON 数据提供简单的逻辑补丁,实现平滑的过渡。

JS 的隐患

官方在 v7 后逐渐不推荐纯 JS 模组用于大型复杂项目。因为 JS 在 Rhino 引擎下的运行效率远不及原生 Java,大量计算容易引起卡顿;同时它缺乏严格的类型检查,很容易导致游戏悄无声息地出现 Bug 或在手机端崩溃。


3. Java / Kotlin:无所不能的创世之力

当你需要极高的运行效率、庞大的新系统(比如一整套全新的自定义星球生态生成器、全新的多核反应堆物理网络计算),你就必须使用 Java(或者兼容它的 Kotlin)。

还是以《饱和火力》为例,如果你打开它的 mod.json

json
{
  "name": "Saturation firepower",
  "java": true,
  "main": "sf.SF"
}

那个显眼的 "java": true 就是在向游戏引擎宣告:“我不满足于你的默认解析,我要用我自己的代码来全面接管游戏!” 同时,模组目录下的 classes.dex 就是被编译打包好的 Java/Kotlin 字节码核心。

为什么推荐最终走向 Java?

  • 极致的性能:Java 代码会被编译后运行,速度远超解释执行的 JS。对于动辄满屏单位、子弹和物流的 Mindustry,性能就是生命线。
  • 完整的权限:你可以随心所欲地继承原版的 Turret.java,重写里面的 updateTile() 方法,想怎么渲染图层、怎么计算复杂的链式伤害,全凭你做主。
  • IDE 的完美支持:使用 IntelliJ IDEA 等现代集成开发环境,写代码时会自动提示所有原版的类和方法名,并自动帮你排查错误,比在文本编辑器里盲敲 JSON 和 JS 要高效一万倍。

结语:踏上新的征程

至此,我们的《Mindustry JSON 模组开发指南》就要正式落下帷幕了。

从 0x01 的初识 mod.json,到亲自配置方块、子弹、特效,再到 0x09 学会主动去 GitHub 翻阅原版源码,你已经具备了一个优秀 JSON 架构师的所有素养,完全有能力独立撑起一个中大型模组的内容填充。

如果你渴望突破数据的桎梏,想要在编译器中敲下属于自己的 public class MyBlackholeTurret extends Turret,去创造前所未有的物理法则,请移步本站的 Java 模组开发教程目录

感谢你的阅读与实践。星辰大海,我们 Java 见!