Closed lab3 closed 1 year ago
I think I found the issue. In this method in your mixin
@Inject(method = "tickChildren", at = @At(value = "INVOKE",
target = "Lnet/minecraft/server/MinecraftServer;getWorldArray()[Lnet/minecraft/server/level/ServerLevel;"))
public void tickWorlds(BooleanSupplier shouldKeepTicking, CallbackInfo ci) {
There is a loop where each levels tick gets called
DimThread.swapThreadsAndRun(() -> {
try {
serverWorld.tick(shouldKeepTicking);
} catch (Throwable throwable) {
crash.set(new CrashInfo(serverWorld, throwable));
}
}, serverWorld, serverWorld.getChunkSource());
But in the Forge Implementation of tickChildren there is a similar loop where the Forge tick events are being fired in addition to the level's tick method being called.
net.minecraftforge.event.ForgeEventFactory.onPreLevelTick(serverlevel, p_129954_);
try {
serverlevel.tick(p_129954_);
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.forThrowable(throwable, "Exception ticking world");
serverlevel.fillReportDetails(crashreport);
throw new ReportedException(crashreport);
}
net.minecraftforge.event.ForgeEventFactory.onPostLevelTick(serverlevel, p_129954_);
Here is the full Forge implementation of tickChildren for reference. Unless I'm missing something, I think the forge specific items would need to be implemented in your mixin for full Forge compatibility.
public void tickChildren(BooleanSupplier p_129954_) {
this.profiler.push("commandFunctions");
this.getFunctions().tick();
this.profiler.popPush("levels");
for(ServerLevel serverlevel : this.getWorldArray()) {
long tickStart = Util.getNanos();
this.profiler.push(() -> {
return serverlevel + " " + serverlevel.dimension().location();
});
if (this.tickCount % 20 == 0) {
this.profiler.push("timeSync");
this.playerList.broadcastAll(new ClientboundSetTimePacket(serverlevel.getGameTime(), serverlevel.getDayTime(), serverlevel.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)), serverlevel.dimension());
this.profiler.pop();
}
this.profiler.push("tick");
net.minecraftforge.event.ForgeEventFactory.onPreLevelTick(serverlevel, p_129954_);
try {
serverlevel.tick(p_129954_);
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.forThrowable(throwable, "Exception ticking world");
serverlevel.fillReportDetails(crashreport);
throw new ReportedException(crashreport);
}
net.minecraftforge.event.ForgeEventFactory.onPostLevelTick(serverlevel, p_129954_);
this.profiler.pop();
this.profiler.pop();
perWorldTickTimes.computeIfAbsent(serverlevel.dimension(), k -> new long[100])[this.tickCount % 100] = Util.getNanos() - tickStart;
}
this.profiler.popPush("connection");
this.getConnection().tick();
this.profiler.popPush("players");
this.playerList.tick();
if (net.minecraftforge.gametest.ForgeGameTestHooks.isGametestEnabled()) {
GameTestTicker.SINGLETON.tick();
}
this.profiler.popPush("server gui refresh");
for(int i = 0; i < this.tickables.size(); ++i) {
this.tickables.get(i).run();
}
this.profiler.pop();
}
Hi, thx for reporting and the assistance to find the cause of this issue. I will fix it asap. This could probably fix some of other incompatibilities too.
Fixed in v1.2.8
Glad to help
I could use a little assistance. I'm looking into a bug report in our mod where some features stop working when DimensionalThreading-Reforged is installed.
https://github.com/iron431/Irons-Spells-n-Spellbooks/issues/10
The problem I'm seeing is that TickEvent.LevelTickEvent event is not fired when "gamerule dimthread_active" is set to true. Soon as you set it to false the event starts firing again. I'm not familiar enough with DimensionalThreading-Reforged to know what is going on but I'm hoping you might be able to point us in the right direction.