修复 gen_1_21 渲染:1.21 的 gameLoadFinished 门禁(第 13 处世代差异)

症状:gen_1_21 启动成功、数据注入成功(loadedChunks=49),
      但 chunksRendered=0、画面停在 Mojang 加载屏(distinctColors≈199)。

根因(1.21 GameRenderer.render 内部,编译期看不出):
    boolean ok = minecraft.isGameLoadFinished();
    if (ok && renderLevel && level != null) renderLevel(...);
  该标志只在 reloadResourcePacks 回调(onResourceLoadFinished)里置 true。
  我们不跑异步 reload(会死锁)⇒ 恒 false ⇒ 世界永不渲染。
  1.20.x 无此门禁 ⇒ gen_1_20 从未受影响。

修法:gen_1_21 的 McfoldBridge 加 markGameLoadFinished(反射置位),
      在 boot 里 shader 编译后调用 —— 差异留在 Java 侧。

★ 教训:这类差异不崩不报错,只是画面不对 ⇒ 判据必须用
  chunksRendered/distinctColors,不能只看进程活着。

顺带修:tick 异常不再静默吞掉(try{tick()}catch(ignore){} → 打印第一帧异常)
新增诊断字段:screenNow/overlayNow/levelNow/playerNow/noRender

实测:gen_1_21 现在 chunksRendered=25、has_world_content=True
      (草地/天空/太阳/HUD 正常)
This commit is contained in:
JianFeeeee
2026-09-25 19:45:24 +08:00
parent bea69b2556
commit d0fb5517a0
4 changed files with 79 additions and 2 deletions

View File

@ -79,3 +79,35 @@ Java 编译期绑定签名。实测:
不走老版 `downloads.classifiers` 结构 ⇒ 两种形态都要认。
- 跳过音频资源可省 **3744/3911 条**(仅 167 条实际下载),
实测 1.21.1 全量 274 文件 / 200MB / 32s,0 失败。
## 补充 2:1.21 的 gameLoadFinished 门禁(第 13 处,编译期看不出)
gen_1_21 曾经「启动成功但渲染 0 区块、画面停在 Mojang 加载屏」。
根因在 `GameRenderer.render(DeltaTracker, boolean)` 内部(1.21 反编译):
```java
boolean ok = this.minecraft.isGameLoadFinished();
if (ok && renderLevel && this.minecraft.level != null) {
this.renderLevel(deltaTracker); // ← 只有 ok 才渲染世界
}
```
而该标志只在 **`reloadResourcePacks()` 的回调**里被置 true
(`Minecraft.onResourceLoadFinished` 第 628 行)。
⇒ 我们不跑异步 reload(会死锁,见前文)⇒ 该位恒 false ⇒ 世界永不渲染。
**1.20.x 没有这个门禁**,所以 gen_1_20 一直正常。
修法(在 Java 侧,符合「差异留在 Java」的原则):
```java
// gen_1_21/net/minecraft/client/renderer/McfoldBridge.java
public static void markGameLoadFinished(Minecraft mc) {
Field f = Minecraft.class.getDeclaredField("gameLoadFinished");
f.setAccessible(true);
f.setBoolean(mc, true);
}
```
★ 这类差异**只在上层失败**,不会崩、不会报错,只是画面停在加载屏 ——
所以判据要用「`chunksRendered` / `distinctColors`」,不能只看「进程活着」。