LWJGL3ify

LWJGL3ify

允许在最新的Java和LWJGL版本上运行老版本的Minecraft

性能

LWJGL3ify

为 Minecraft 1.7.10 引入 LWJGL3 和现代 Java 版本。集成了 RetroFuturaBootstrap 作为一个灵活的早期加载插件系统。

使用时,只需将主 jar 放入 mods/ 目录,并像往常一样配置使用 Java 8 启动。启动时,应出现一个窗口提示您选择用于重新启动的现代 Java 版本以及该 Java 安装的 JVM 设置。如果没有出现,您应该从首选供应商处下载并安装现代 Java 版本,目前推荐使用 Java 17 和 21。

兼容性

虽然本模组力求达到最大兼容性,但不可避免地会有一些模组目前无法与 lwjgl3ify 兼容。请检查我们的问题追踪器是否已列出它们,如果没有,请提交一个 issue,包括崩溃报告(如果有)、游戏日志以及关于哪些功能无法正常工作的信息。

调整配置

如果您想调整窗口选项、原始鼠标输入、OpenGL 上下文属性或其他更高级的设置,请在首次启动后查看 config/lwjgl3ify.cfg 中的配置文件,或在游戏中查看 lwjgl3ify 模组选项。

服务端安装

首先,从整合包 zip 或使用 Forge 的安装程序安装一个可用的 Forge 服务端。然后,将模组 jar(以及按需的 unimixins、hodgepodge 和 gtnhlib)安装到 mods/ 目录,并下载 forgePatches jar。将 forgePatches jar 放在与 forge-universal 和 minecraft 服务端 jar 相同的文件夹中。不支持 Thermos/Crucible/Hybrid 服务端! Lwjgl3ify 也依赖于 Unimixins。将 forgePatches jar 重命名为 lwjgl3ify-forgePatches.jar。从本模组的源代码中获取 java9args.txt。现在,您可以使用类似于下面的命令启动服务端,假设您 PATH 上的第一个 java 可执行文件是 java 17/21/更新版本:

java -Xmx6G -Xms6G @java9args.txt -jar lwjgl3ify-forgePatches.jar nogui

它是如何工作的? (非常技术性的细节)

实现在旧版 Minecraft 上使用现代 Java 和 LWJGL 需要几个组件,lwjgl3ify 具体实现了以下内容:

  • 一个游戏重新启动器,用于修改加载到 Java 类路径中的库列表 - 以安装 LWJGL3,以及我们的 forgePatches jar,其中包含诸如 ASM 9 或新版 Apache Commons 之类的库。
  • 一个自定义服务端启动器 jar,带有修改后的 Class-Path META-INF 清单条目(集成到了我们的 forgePatches jar 中)。
  • 一个免费开源的 launchwrapper 替代品,具有兼容 Java 9+ 的类路径发现机制和更广泛的转换器功能,位于 https://github.com/GTNewHorizons/RetroFuturaBootstrap。
  • 为 JVM 添加许多 add-opens 标志,以允许反射到 JVM 内部。不幸的是,许多库和模组依赖于此才能工作,甚至包括像 Netty 情况下的 java.text 或 nio 内部这样奇怪的部分。
  • 一个部分自动生成的兼容性垫片,将 lwjgl2 API 调用重定向到匹配的 lwjgl3 调用(位于 src/main/java/org/lwjglx、src/generated/java/org/lwjglx),生成器位于 src/util/java。
  • 针对从 lwjgl3 中移除的类(例如 Display)的虚拟 org/lwjgl/* 类,供依赖在类路径中找到这些类(例如 mixin 元数据)的模组使用。
  • 用于崩溃报告替代的 GL 供应商信息提供程序,旧的提供程序在从没有有效 OpenGL 上下文的线程中使用时会导致 JVM 崩溃。
  • Asm 转换器:
    • 一个 Asm 转换器,在对类进行所有其他转换之后,将对 org/lwjgl 的任何访问重命名为 org/lwjglx - 在 LwjglRedirectTransformer.java 中。
    • javax/xml/bind -> jakarta/xml/bind/ asm 转换器和一个阴影化的 jakarta.xml.bind 版本,因为该 API 已从 JRE 11 中移除。
    • 可扩展枚举转换器(根据 LGPL 许可从 Minecraft 1.19.3 的 Forge 复制过来),用于替换大量 EnumHelper 的用法。
    • Object holders unfinalizer,用于消除重写 Forge 中 static final 字段的需要。
    • FixConstantPoolInterfaceMethodRefHelper 是一个转换器,用于修复 javac 8/asm 5.0 reobfuscator 的一个错误,该错误在使用接口方法的 method handles 时会在常量池中生成错误的条目。
  • Mixins:
    • 修改 Object holder 以不再写入 static final 字段。
    • 更改 JarDiscoverer 以忽略 module-info.class 和 META-INF/versions/* 类,因为它不兼容 Java 9。
    • 使用 PostMixinTransformInjector 将我们的 asm 转换器移到 mixin 处理之后运行。
  • 来自现代 Forge 的 UnsafeHacks 类,经过修改以在更多用例中工作,用于替换某些无法可行/容易地移除 final 的 static final 写入。
  • Forge 补丁,这些是来自 Forge 的修改类,由于加载过早而无法转换 - 因此我们在类路径中的 Forge 之前加载一个 forgePatches jar 来替换它们:
    • EventSubscriptionTransformer:Java 17 中子类注解描述符的格式略有变化,这使得注解发现与两者兼容。
    • TerminalTransformer:修改以接受比 asm5 支持的更新的类文件。
    • ClassPatchManager:将 Pack200 实现切换到 Apache Commons Compress,因为它已从更新的 JDK 中移除。
    • TracingPrintStream:commons-compress 会关闭 System.out,这阻止了这种情况的发生。
    • CoreModManager:解决系统类加载器不再是 URLClassLoader 的问题。
    • FMLSecurityManager:修复一些数组索引越界异常,它在 Java 17 中也被弃用,一旦新的 API 可用就需要替换。
    • EnumHelper:使用基于可扩展枚举转换器和 unsafe hacks 的新变体替换所有 enumhelper API。
  • 利用 LWJGL3 功能的额外性能增强 mixins:
    • 基于 STB_image 的图像加载器,速度远快于 Image4J。
    • 基于 STB_rectpack 的纹理缝合器,处理数万个纹理时几乎瞬间完成,而原版代码需要很多秒才能将那么多纹理缝合到一个图集中。