Register inventory tabs from the client proxy, not the mod class

Deferring registration to loadComplete is right - TConstruct needs to have
registered first - but naming TabRegistry and the tab classes in CustomNpcs put
client-only GUI types in a class the server loads, which the verifier resolves
at link time regardless of any runtime side check. A proxy hook keeps them in
ClientProxy while still running at the same point.
This commit is contained in:
KAMKEEL committed 2026-08-11 05:56:08 -04:00
1 parent 74511b7449
commit c6e361f8e6
3 files changed
+25 -13

No files matched your search

@@ -225,6 +225,14 @@ public class CommonProxy implements IGuiHandler {
public void buildPackageIndex() {
}
/**
* Called from the mod's FMLLoadCompleteEvent, after every other mod has finished loading.
* Anything that has to observe another mod's registrations belongs here rather than in
* load(), and it stays on the proxy so client-only types never reach the server.
*/
public void loadComplete() {
}
public boolean isScriptingEnabled() {
return ConfigScript.ScriptingEnabled;
}
+4 -13
View File
@@ -64,7 +64,6 @@ import nikedemos.markovnames.generators.MarkovSlavic;
import nikedemos.markovnames.generators.MarkovSpanish;
import nikedemos.markovnames.generators.MarkovWelsh;
import noppes.npcs.compat.PixelmonHelper;
import noppes.npcs.config.ConfigClient;
import noppes.npcs.config.ConfigMain;
import noppes.npcs.config.LoadConfiguration;
import noppes.npcs.config.legacy.LegacyConfig;
@@ -120,9 +119,6 @@ import noppes.npcs.entity.old.EntityNpcNagaMale;
import noppes.npcs.entity.old.EntityNpcSkeleton;
import noppes.npcs.scripted.NpcAPI;
import somehussar.janino.AdvancedClassFilter;
import tconstruct.client.tabs.InventoryTabCustomNpc;
import tconstruct.client.tabs.InventoryTabVanilla;
import tconstruct.client.tabs.TabRegistry;
import java.io.File;
import java.util.HashSet;
@@ -347,15 +343,10 @@ public class CustomNpcs {
@EventHandler
public void loadComplete(FMLLoadCompleteEvent ev) {
if (ev.getSide().isClient()) {
if (ConfigClient.InventoryGuiEnabled) {
MinecraftForge.EVENT_BUS.register(new TabRegistry());
if (TabRegistry.getTabList().isEmpty()) {
TabRegistry.registerTab(new InventoryTabVanilla());
}
TabRegistry.registerTab(new InventoryTabCustomNpc());
}
}
// Runs after every other mod has loaded. Kept on the proxy: the client side registers
// inventory tabs, and naming those types here would drag client-only GUI classes into
// a class the server loads.
proxy.loadComplete();
proxy.buildPackageIndex();
// Load built-in animations on the client so they're available for ability preview.
@@ -854,6 +854,19 @@ public class ClientProxy extends CommonProxy {
return Minecraft.getMinecraft().currentScreen != null;
}
@Override
public void loadComplete() {
// Deferred from load() so TConstruct has registered its own tabs first - registering
// ours before it left the vanilla tab duplicated.
if (ConfigClient.InventoryGuiEnabled) {
MinecraftForge.EVENT_BUS.register(new TabRegistry());
if (TabRegistry.getTabList().isEmpty()) {
TabRegistry.registerTab(new InventoryTabVanilla());
}
TabRegistry.registerTab(new InventoryTabCustomNpc());
}
}
public void buildPackageIndex() {
try {
PackageFinder.init(Thread.currentThread().getContextClassLoader());