From 08739cadabb108ded43a2de14140bf94e1a25f9a Mon Sep 17 00:00:00 2001 From: Sebastian Hartte Date: Wed, 2 Apr 2025 21:07:16 +0100 Subject: [PATCH 1/2] Fix early client lifecyle events and introduce ClientResourceLoadFinishedEvent. The NeoForge event bus also starts earlier now. --- .../net/minecraft/client/Minecraft.java.patch | 22 +++++++++---- .../neoforge/client/ClientHooks.java | 8 +++++ .../ClientResourceLoadFinishedEvent.java | 31 +++++++++++++++++++ .../client/event/ClientTickEvent.java | 2 ++ .../client/loading/ClientModLoader.java | 4 --- .../neoforge/internal/CommonModLoader.java | 3 ++ .../server/loading/ServerModLoader.java | 2 -- 7 files changed, 60 insertions(+), 12 deletions(-) create mode 100644 src/client/java/net/neoforged/neoforge/client/event/ClientResourceLoadFinishedEvent.java diff --git a/patches/net/minecraft/client/Minecraft.java.patch b/patches/net/minecraft/client/Minecraft.java.patch index dbfe95a7087..e9a2b607827 100644 --- a/patches/net/minecraft/client/Minecraft.java.patch +++ b/patches/net/minecraft/client/Minecraft.java.patch @@ -1,5 +1,3 @@ ---- a/net/minecraft/client/Minecraft.java -+++ b/net/minecraft/client/Minecraft.java @@ -430,7 +_,6 @@ } }, Util.nonCriticalIoPool()); @@ -90,6 +88,14 @@ this.selfTest(); } +@@ -668,6 +_,7 @@ + } + + private void onResourceLoadFinished(@Nullable Minecraft.GameLoadCookie p_299896_) { ++ net.neoforged.neoforge.client.ClientHooks.fireResourceLoadFinishedEvent(!this.gameLoadFinished); + if (!this.gameLoadFinished) { + this.gameLoadFinished = true; + this.onGameLoadFinished(p_299896_); @@ -704,6 +_,8 @@ runnable = () -> this.setScreen(screen); } @@ -311,11 +317,13 @@ if (!itemstack.isEmpty() && this.gameMode.useItem(this.player, interactionhand) instanceof InteractionResult.Success interactionresult$success1) { if (interactionresult$success1.swingSource() == InteractionResult.SwingSource.CLIENT) { -@@ -1675,6 +_,8 @@ +@@ -1675,6 +_,10 @@ public void tick() { this.clientTickCount++; -+ net.neoforged.neoforge.client.ClientHooks.fireClientTickPre(); ++ if (this.gameLoadFinished) { ++ net.neoforged.neoforge.client.ClientHooks.fireClientTickPre(); ++ } + if (this.level != null && !this.pause) { this.level.tickRateManager().tick(); @@ -336,12 +344,14 @@ } profilerfiller.popPush("animateTick"); -@@ -1810,6 +_,8 @@ +@@ -1810,6 +_,10 @@ profilerfiller.popPush("keyboard"); this.keyboardHandler.tick(); profilerfiller.pop(); + -+ net.neoforged.neoforge.client.ClientHooks.fireClientTickPost(); ++ if (this.gameLoadFinished) { ++ net.neoforged.neoforge.client.ClientHooks.fireClientTickPost(); ++ } } private boolean isLevelRunningNormally() { diff --git a/src/client/java/net/neoforged/neoforge/client/ClientHooks.java b/src/client/java/net/neoforged/neoforge/client/ClientHooks.java index 365a7e62987..8a8f7329d6e 100644 --- a/src/client/java/net/neoforged/neoforge/client/ClientHooks.java +++ b/src/client/java/net/neoforged/neoforge/client/ClientHooks.java @@ -150,6 +150,7 @@ import net.neoforged.neoforge.client.event.ClientPauseChangeEvent; import net.neoforged.neoforge.client.event.ClientPlayerChangeGameTypeEvent; import net.neoforged.neoforge.client.event.ClientPlayerNetworkEvent; +import net.neoforged.neoforge.client.event.ClientResourceLoadFinishedEvent; import net.neoforged.neoforge.client.event.ClientTickEvent; import net.neoforged.neoforge.client.event.ComputeFovModifierEvent; import net.neoforged.neoforge.client.event.ConfigureMainRenderTargetEvent; @@ -1052,6 +1053,13 @@ public static void fireRenderFramePost(DeltaTracker partialTick) { RenderSystem.ensurePipelineModifiersEmpty(); } + /** + * Fires {@link ClientResourceLoadFinishedEvent}. + */ + public static void fireResourceLoadFinishedEvent(boolean initial) { + NeoForge.EVENT_BUS.post(new ClientResourceLoadFinishedEvent(initial)); + } + /** * Fires {@link ClientTickEvent.Pre}. Called from the head of {@link Minecraft#tick()}. */ diff --git a/src/client/java/net/neoforged/neoforge/client/event/ClientResourceLoadFinishedEvent.java b/src/client/java/net/neoforged/neoforge/client/event/ClientResourceLoadFinishedEvent.java new file mode 100644 index 00000000000..4afe6320f71 --- /dev/null +++ b/src/client/java/net/neoforged/neoforge/client/event/ClientResourceLoadFinishedEvent.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.event; + +import net.neoforged.bus.api.Event; + +/** + * Fires after the client has completed loading or reloading its resources + * successfully. + *

+ * When the client first starts up, this event is fired after the resource + * load, but before the client has set up the initial screens, and before + * we emit the first {@link ClientTickEvent}. + */ +public class ClientResourceLoadFinishedEvent extends Event { + private final boolean initial; + + public ClientResourceLoadFinishedEvent(boolean initial) { + this.initial = initial; + } + + /** + * @return True if the reload that completed was the initial resource load of the client. + */ + public boolean isInitial() { + return initial; + } +} diff --git a/src/client/java/net/neoforged/neoforge/client/event/ClientTickEvent.java b/src/client/java/net/neoforged/neoforge/client/event/ClientTickEvent.java index 78c33948c09..990fc7977e0 100644 --- a/src/client/java/net/neoforged/neoforge/client/event/ClientTickEvent.java +++ b/src/client/java/net/neoforged/neoforge/client/event/ClientTickEvent.java @@ -11,6 +11,8 @@ * Base class of the two client tick events. *

* For the event that fires once per frame (instead of per tick), see {@link RenderFrameEvent}. + *

+ * Note that tick events will only start being emitted once the first {@link ClientResourceLoadFinishedEvent resource reload has completed}. * * @see ClientTickEvent.Pre * @see ClientTickEvent.Post diff --git a/src/client/java/net/neoforged/neoforge/client/loading/ClientModLoader.java b/src/client/java/net/neoforged/neoforge/client/loading/ClientModLoader.java index 35ab6997e43..56bece72c91 100644 --- a/src/client/java/net/neoforged/neoforge/client/loading/ClientModLoader.java +++ b/src/client/java/net/neoforged/neoforge/client/loading/ClientModLoader.java @@ -26,7 +26,6 @@ import net.neoforged.fml.loading.EarlyLoadingScreenController; import net.neoforged.neoforge.client.config.NeoForgeClientConfig; import net.neoforged.neoforge.client.gui.LoadingErrorScreen; -import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.internal.CommonModLoader; import net.neoforged.neoforge.logging.CrashReportExtender; import net.neoforged.neoforge.resource.ResourcePackLoader; @@ -128,9 +127,6 @@ public static Runnable completeModLoading(Runnable initialScreensTask) { return () -> Minecraft.getInstance().setScreen(new LoadingErrorScreen(error.getIssues(), dumpedLocation, () -> {})); } - // We can finally start the game eventbus up - NeoForge.EVENT_BUS.start(); - if (!warnings.isEmpty()) { if (showWarnings) { return () -> Minecraft.getInstance().setScreen(new LoadingErrorScreen(warnings, null, initialScreensTask)); diff --git a/src/main/java/net/neoforged/neoforge/internal/CommonModLoader.java b/src/main/java/net/neoforged/neoforge/internal/CommonModLoader.java index 0db15ddee1c..f729010b642 100644 --- a/src/main/java/net/neoforged/neoforge/internal/CommonModLoader.java +++ b/src/main/java/net/neoforged/neoforge/internal/CommonModLoader.java @@ -20,6 +20,7 @@ import net.neoforged.fml.event.lifecycle.InterModProcessEvent; import net.neoforged.fml.loading.FMLEnvironment; import net.neoforged.fml.loading.FMLPaths; +import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.network.registration.NetworkRegistry; import net.neoforged.neoforge.registries.GameData; import net.neoforged.neoforge.registries.RegistryManager; @@ -63,6 +64,8 @@ protected static void begin(Runnable periodicTask, boolean datagen) { ConfigTracker.INSTANCE.loadConfigs(ModConfig.Type.COMMON, FMLPaths.CONFIGDIR.get()); }); } + + NeoForge.EVENT_BUS.start(); } protected static void load(Executor syncExecutor, Executor parallelExecutor) { diff --git a/src/main/java/net/neoforged/neoforge/server/loading/ServerModLoader.java b/src/main/java/net/neoforged/neoforge/server/loading/ServerModLoader.java index 87c7b9cc46b..d166d3e5cb4 100644 --- a/src/main/java/net/neoforged/neoforge/server/loading/ServerModLoader.java +++ b/src/main/java/net/neoforged/neoforge/server/loading/ServerModLoader.java @@ -11,7 +11,6 @@ import net.neoforged.fml.ModLoadingException; import net.neoforged.fml.ModLoadingIssue; import net.neoforged.fml.ModWorkManager; -import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.internal.CommonModLoader; import net.neoforged.neoforge.logging.CrashReportExtender; import net.neoforged.neoforge.server.LanguageHook; @@ -44,7 +43,6 @@ public static void load() { LOGGER.warn(Logging.LOADING, "{} [{}]", issue.translationKey(), issue.translationArgs()); } } - NeoForge.EVENT_BUS.start(); } public static boolean hasErrors() { From 81a3e3f306440067fd474af38be2da54cb32be2b Mon Sep 17 00:00:00 2001 From: Sebastian Hartte Date: Wed, 2 Apr 2025 21:16:08 +0100 Subject: [PATCH 2/2] Fix early client lifecyle events and introduce ClientResourceLoadFinishedEvent. The NeoForge event bus also starts earlier now. --- patches/net/minecraft/client/Minecraft.java.patch | 2 ++ 1 file changed, 2 insertions(+) diff --git a/patches/net/minecraft/client/Minecraft.java.patch b/patches/net/minecraft/client/Minecraft.java.patch index e9a2b607827..2f28c4f3fee 100644 --- a/patches/net/minecraft/client/Minecraft.java.patch +++ b/patches/net/minecraft/client/Minecraft.java.patch @@ -1,3 +1,5 @@ +--- a/net/minecraft/client/Minecraft.java ++++ b/net/minecraft/client/Minecraft.java @@ -430,7 +_,6 @@ } }, Util.nonCriticalIoPool());