全自动电棍 发表于 2025-12-31 23:23:03

【杂谈】Java升级、FastRender、和ModLoader。

本帖最后由 全自动电棍 于 2025-12-31 23:32 编辑

让我们来聊聊模组,也就是“Mod”。
“Mod”,是“Modification”的简称,指对游戏内容进行修改的外加第三方软件。
尽管模组这个译名听起来更像“Module”而非“Modification”,但我们通常说的“模组”指的就是这个。

正如其名,Mod是一种对游戏的修改。但在我看来,远星星号的“Mod”更加接近于扩展(Extension),它们通常是加入新的舰船、武器、故事线、以及机制,却很少修改或劫持游戏原有的机制或做出什么触及底层的修改。而隔壁Minecraft Modding社区却并非如此。

显然,塑造这一情形的不只有技术上的限制,自然还有社区开发者文化对此的消极看法——“我们已经有足够开放的API了,那就好好用着。” “反射是给开发者添乱。”

直到Java升级套件的出现。

1.Mikohime与Jar包二进制Patch

在大伙难以忍受Java7的落后性能与特性,以至于迫使开发者转投Kotlin怀抱之时——
Mikohime带着更好的性能和更新的Java出现了。

Mikohime Java升级套件的出现毫无疑问扩展了远神社区对“Mod”的定义范围。
既然你能接受从网络上下载效果不明的压缩包解压并安装到mods文件夹,那为什么不能接受一个需要安装在根目录的“Mod”?

我此前的一篇文章已经分析过了Mikohime的核心修改部分,有兴趣可以看看。

书归正题,Mikohime的修改其实很粗糙,是直接Patch游戏Jar包并与依赖一起打包。
而这实际上与直接分发修改版游戏无异,同时也意味着你使用Java升级套件提供的bat实际上是在启动一份修改过的游戏,而非你的安装,不过是共享相同的资源文件罢了。

这其实引发了一个小问题:增强游戏性能算不算“正当”的“模组”? 如果只是为了“让游戏性能更好”,大伙似乎比某些入(EN)更容易接受这种越界。

显然,FastRender在这方面做的更好。

2.FastRender与类路径覆盖

FastRender,正如其名,不难猜出这是一个通过覆盖远神渲染管线为自定义实现以提升游戏性能的“Mod”。

其实早在我给远神编写Fabric GameProvider的前期调研时便注意到了这个“模组”,不过中文论坛上对其的讨论几乎没有,如果有条件我会对其进行搬运。

FastRander对游戏进行修改的方式其实很简单,通过同名类替换远神渲染相关基础设施并桥接到自定义实现。
只需要在启动参数中的Classpath中将上述内容组成的jar包前置,剩下的事情Classloader会自己搞定。

只有一个jar包和一个bat文件,不再需要分发游戏本体,很“合法”,不是吗?

但它们最终都会遇到并尝试解决一个问题,并且这个问题已经被解决过了。

3.Modloader:NanoForge - Evil Alien Hacks

NanoForge是我在今年(?)十月份用LaunchWarpper搓出来的一个小玩具。

对于一位身经百战的方块入来说手搓一个Modloader并没有什么困难的,尤其是如今Mixin大行其道的时代,有太多的例子可用,有太多的资源可以接触,比如说...这个。

但现在让我们离开远神,前往米拉克福特,回到NeoForge以前、Fabric兴起之前、cpw写出LaunchWarpper之前、回到FML、RML与Modloader出现之前。

一个洪荒的年代,一切的修改都以类文件存在,一切的安装必须覆盖Jar包,一切的改动都必须删除META-INF中的签名(注:远神没有)。

这就是未来远神即将要触碰到的问题——两个CoreMod无法修改同一个类。
但正如前文所述,这是一个已经被解决过的问题。


我们应当感谢cpw为了替代Relauncher而编写的LaunchWarpper,它并不像它的替代品ModLauncher那样复杂,也具有足够的泛化能力可以用于其他Java应用。

而且Forge 1.12.1~1.8.9的CoreMod系统很简单,本质上是对LuanchWarpper的Tweaker系统的封装,并且提供了级联注入和排序功能。

显然我现在已经部分地完成了这些东西,你可以在NanoForge的dev分支上见到。

4.Why?

但现在又回到了一个问题:“我们为什么需要CoreMod(With Modloader)?”

显然,是非曲折难以论说。
可能是需要获取一个数值但API并没有提供它,并且也不能使用反射;
也可能是更新到更新版本的Java时再一次出现了兼容问题。

当然我们更常见的是以下情形,就以最近的一个例子说明:
Alex在论坛上和渲染驱动<local4>空指针报错进行了吉列的斗争并添加了空值检查,并宣布在下一个发布修复。
但显然,内核汉化导致我们几乎永远不可能使用下一个发布,除非汉化更新或放弃部分汉化,sst汉化有多久没有更新过了?
尽管官网论坛有人对这一问题制作了类文件补丁,但这极有可能回到我们上面讲的那个问题——两个CoreMod无法修改同一个类。

ML可以解决这个。
补丁可以通过编写类转换器实现,汉化也可以在类转换时替换所有字符串常量实现。
兼容性++

Modded Better Than Vanilla。

感谢大伙耐心看我这么多牢骚。
祝大伙新年快乐!

Colt_SCW 发表于 2025-12-31 23:32:58

虽然看不懂,但意思是下个版本不用启动器的话汉化要更难了(?){:tieba_30:}

安超锤头 发表于 2025-12-31 23:36:27

耶咦耶~
耶咦耶咦~~耶咦耶哦哦~~耶咦耶咦~耶咦耶阿哦吼~~
棍兄, 提前给你拜个早年呐!
新年快乐!


全自动电棍 发表于 2025-12-31 23:36:45

Colt_SCW 发表于 2025-12-31 23:32
虽然看不懂,但意思是下个版本不用启动器的话汉化要更难了(?)

大意为:内核汉化缺乏迁移性,建议直接上字节码转换,还有老东西我来给你搞花活来咯😋

丧失病狂 发表于 2026-1-1 00:27:55

内核汉化就是这样子啦,要么官方直接给接口,要么搞外挂汉化,要么就只能上笨办法。
不过棍兄的意思是以后可以像打mod那样制作和安装汉化咩?

全自动电棍 发表于 2026-1-1 09:42:43

本帖最后由 全自动电棍 于 2026-1-1 09:45 编辑


以后可以像打mod那样制作和安装汉化
差不多是这样

此前我有发帖询问过关于汉化工作流程中的一些细节,汉化组的回复如下:
硬编码文本翻译流程基本是先解出所有常量,然后人工识别需要翻译的字串,完成翻译之后对直接对jar常量批量替换。翻译过程不涉及重编译,所以混淆产生的影响仅限于增加解读需翻译字串的难度。
实际上替换这一过程也可以是动态的,即:对在类转换阶段找出的所有字符串常量,进行查表替换。
而我在很久之前就有这种想法,但一直没做,可能最终目标是把这个移植过来。
另外在最理想的情况下这种方法可以保证跨版本不变的部分依旧可以命中并翻译,但可能的代价是拖慢游戏启动速度。

jfxdz 发表于 2026-1-1 10:03:13

全自动电棍 发表于 2026-1-1 09:42
差不多是这样

此前我有发帖询问过关于汉化工作流程中的一些细节,汉化组的回复如下:


那么,除了启动慢以外,对游戏性能影响呢?

丧失病狂 发表于 2026-1-1 13:10:40

jfxdz 发表于 2026-1-1 10:03
那么,除了启动慢以外,对游戏性能影响呢?

不会有什么影响的,本质上只是读取游戏的时候现场安装一边汉化包,又不是外挂汉化

jfxdz 发表于 2026-1-2 09:07:59

丧失病狂 发表于 2026-1-1 13:10
不会有什么影响的,本质上只是读取游戏的时候现场安装一边汉化包,又不是外挂汉化 ...

那我现在确实非常期待这个了,启动载入满但是汉化更容易,并且不会拖累游戏性能
现在看这个是解决了最大痛点的玩意

悠远星 发表于 2026-1-4 13:37:58

我原来奇怪为什么每个版本还要重新汉化,合着是直接修改类文件的字符串常量。
用反射确实会方便迁移一些。

全自动电棍 发表于 2026-1-4 19:15:05

本帖最后由 全自动电棍 于 2026-1-4 19:21 编辑

孩子们,大失败

我从paratranz上扒拉下来的数据清洗的不是很干净 有键值重叠问题
并且有些类还不能直接替换ldc 疑似又回到得对类结构的依赖上了

这b混淆真的是


我看要么得分析类特征然后特判仙人 要么就得写个映射表然后用matcher减轻名称变动的影响
这混淆不杀不行了

Rigel. 发表于 2026-1-4 19:39:20

帅otto

LanceACE 发表于 2026-1-7 16:13:02

技术电棍,支持一下
页: [1]
查看完整版本: 【杂谈】Java升级、FastRender、和ModLoader。