Discovering-Minecraft

常用维修技巧(欢迎补充)

此处也不是“妙手”,不过如果没有看过前文的话还建议从更基础的“本手”开始学起。

检修一般流程

首先,如果清楚崩溃前究竟进行了那些更改,崩溃发生后可以先尝试回退那些修改:

如果不能解决(当然也可以二话不说直接开始)就开始翻日志和崩溃报告,有条件的话看一下控制台输出。翻到日志的最后以及崩溃报告的开头处或开头处的最后一个“Caused by”(若有)。

然后直接抓关键词:

按照错误走相应的解决路线即可,常见崩溃的解决一节有相关介绍。必要时,结合一些已知的知识进行分析。如果是Fabric环境,可以在崩溃报告中找到Suspected Mods一栏,其中可能包含了引起问题的Mod的名称。

如果无法自行解决,上网搜索,注意用找到的一些看似比较关键的内容,作为关键词。

还是不行,可以上传崩溃报告和日志,可能的话由启动器导出,在论坛的合适板块提问。不建议使用“MC崩溃”等标题,尽可能既简短又具体的地在标题中描述问题及其发生环境,例如“1.16.4Forge整合包启动崩溃无画面”。除非真正地没有内容可以补充,正文不推荐留空,如果有的话,详细说明最近进行的更改和经验证无效的解决方法。也可以在正文中注明Minecraft版本、Java版本等信息(尽管这些信息在崩溃报告中通常也存在),但通常而言必要性不大,因为这些信息在崩溃报告中也可以被找到。

查找造成崩溃的Mod

一般而言,我们可以在崩溃报告中抓取关键词,如Mod的英文名,Mod的modid或者是Mod的作者。对于Replay、暮色森林(Twilight Forest)这一类知名Mod,这类关键词一般而言很显眼,如果出现了相信很多玩家都能一眼看出。但是也存在一些略显小众的Mod导致的崩溃,这时我们也能通过一般关键词的一些特征来从报错中猜测出一个关键词。

我们要找的关键词通常为名词或连接在一起的名词短语(不全是如此,如机械动力create),但很少是单独的常见词语(但也有例外,例子同上),而且如果有直接含义的话一般会比较长(10个字母以上的很可能就是了),有时采用缩写形式或生僻词(总之之不能直接看出含义)时又相对较短(4个字母左右居多)。

与之相反地,也有一些关键词,可以让我们直接忽略掉那一行,因为那里通常不会有关于Mod的关键词(当然,也不要忘了,Mod不是错误的唯一直接来源):

如果你看到了类似这样的一条输出

com.pixelmonmod.pixelmon.api.storage.PCStorage.get(PCStorage.java:231)

那么这里给出了Mod包名。通常包名的开头是com、net、org、cn、de、us等顶级域名,接下来是Mod作者或者开发团队的名称,如果将这两项反过来,可能就是那个Mod或者作者的官方网站。紧接着,很可能就是Mod的英文名称。有时,Mod会以其Github项目主页为包名来源,此时,Mod真名的位置可能会比较靠后。同时,也有些Mod会把作者名称放在包名的最开始处,Mod名称为第二个,甚至有Mod包名的最前面就是Mod的名称。

有时你可能找到这样的一条消息

Caused by: org.spongepowered.asm.mixin.injection.throwables.InjectionError: Critical injection failure: Callback method onDraw(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;ZILorg/spongepowered/asm/mixin/injection/callback/CallbackInfo;IIFLcom/mojang/math/Matrix4f;Lcom/mojang/blaze3d/vertex/VertexConsumer;ILjava/util/Iterator;Lnet/minecraft/world/level/saveddata/maps/MapDecoration;)V in create.mixins.json:MapRendererMapInstanceMixin failed injection check, (0/1) succeeded. Scanned 1 target(s). Using refmap create.refmap.json

仔细看,里面出现了这么一个文件名

create.mixins.json

这时可以算是不幸中的万幸,关键词直接就是文件名中第一个”.“前面的内容,即“create”。

几道随堂练习:

dk.zlepper.itlt.client.helpers.ClientUtils.getCustomWindowTitle(ClientUtils.java:82)
java.lang.ClassCastException: com.github.alexthe666.rats.server.entity.EntityPlagueDoctor cannot be cast to net.minecraft.entity.merchant.villager.VillagerEntity
com.dhanantry.scapeandrunparasites.util.handlers.SRPEventHandlerBus.tickSpawn(SRPEventHandlerBus.java:1299)

找到可疑的关键词后,我们可以在mcmod.cn上进行搜索。找不到的话,用刚才的关键词后面或前面的词重新搜索。如果还是找不到,可以尝试在通用的搜索引擎、Github、Modrinth或CurseForge上再进行一次搜索。如果搜索无果,试着搜索包名中另外一个疑似的关键词。

当然,如果不能确定关键词或实在懒得到处查找,我们可以直接在Github上进行搜索出现的代码。

1672309660059

假设出现了这么一行日志:

at carpet.utils.SpawnReporter.registerSpawn(SpawnReporter.java:86)

我们可以搜索“carpet.utils.SpawnReporter”,在Code或Commits两栏中我们可能会找到疑似与之相关的Mod出处,Issues中我们甚至可能找到对这一Bug的报告。

说了半天,我们的讨论都是基于日志中有关键词的情况,如果报错时压根就找不到关键词该怎么办?

java.lang.IllegalArgumentException: bound must be positive
    at java.util.Random.nextInt(Unknown Source)
    at net.minecraft.server.v1_12_R1.BiomeJungle.a(SourceFile:82)
    at net.minecraft.server.v1_12_R1.ChunkProviderGenerate.recreateStructures(ChunkProviderGenerate.java:387)
    at org.bukkit.craftbukkit.v1_12_R1.generator.NormalChunkGenerator.recreateStructures(NormalChunkGenerator.java:41)
    at net.minecraft.server.v1_12_R1.Chunk.a(Chunk.java:964)
    at net.minecraft.server.v1_12_R1.Chunk.loadNearby(Chunk.java:935)
    at net.minecraft.server.v1_12_R1.ChunkProviderServer.originalGetChunkAt(ChunkProviderServer.java:173)
    at net.minecraft.server.v1_12_R1.ChunkProviderServer.getChunkAt(ChunkProviderServer.java:140)
    at net.minecraft.server.v1_12_R1.PlayerChunk.a(PlayerChunk.java:112)
    at net.minecraft.server.v1_12_R1.PlayerChunkMap.flush(PlayerChunkMap.java:169)
    at net.minecraft.server.v1_12_R1.WorldServer.doTick(WorldServer.java:320)
    at net.minecraft.server.v1_12_R1.MinecraftServer.D(MinecraftServer.java:801)
    at net.minecraft.server.v1_12_R1.DedicatedServer.D(DedicatedServer.java:406)
    at net.minecraft.server.v1_12_R1.MinecraftServer.C(MinecraftServer.java:679)
    at net.minecraft.server.v1_12_R1.MinecraftServer.run(MinecraftServer.java:577)

这时,我们就只能按照问题出现的时机猜测并结合二分法排查导致问题的Mod。例如此处,我们发现了“NormalChunkGenerator”和“BiomeJungle”,由此可以判定(网络上可以翻译一下虽然很生硬但还是有帮助)问题可能与世界生成有关,而且很可能与丛林生物群系相关。

首先按照猜测移除一部分,可以是大约一半的Mod,但要注意不要破坏Mod的依赖关系。移除后,我们可以重新启动游戏,建立一个新的存档或使用导致问题的存档的一个备份进行测试。如果问题不再出现,被移除的那些Mod的中就包含了导致问题的那一个,这时我们可以将被移除的Mod重新启用一部分;否则,如果相同的问题仍然出现,移除剩下的Mod中的一部分,然后将先前被移除的Mod还原,再次测试。依次往复直到找到导致问题出现Mod。

当然有时候问题不一定是单个Mod导致的,也有可能是多个Mod共同作用的结果。