From 168a3a81ad7a4137af2cff2d1b43e32a532cb327 Mon Sep 17 00:00:00 2001 From: Alex Lee Date: Sun, 28 Dec 2025 18:47:28 +0800 Subject: [PATCH 1/7] Fix runtime error when run with alexmobs --- .gitignore | 2 ++ build.gradle | 1 + .../com/github/alexthe666/citadel/Citadel.java | 6 ++++-- .../citadel/client/ClientEvents.java | 2 +- .../citadel/client/gui/EntityLinkButton.java | 14 +++++++++++--- .../citadel/client/gui/GuiBasicBook.java | 18 ++++++++++++++++-- .../citadel/client/gui/data/LinkData.java | 4 ++-- 7 files changed, 37 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 9746858..beced27 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ runs # Files from Forge MDK forge*changelog.txt + +.vscode \ No newline at end of file diff --git a/build.gradle b/build.gradle index 8297e4c..523c022 100644 --- a/build.gradle +++ b/build.gradle @@ -238,6 +238,7 @@ idea { jar { //classifier 'slim' + duplicatesStrategy = DuplicatesStrategy.EXCLUDE afterEvaluate { configurations.shade.each { dep -> from(project.zipTree(dep)) { diff --git a/src/main/java/com/github/alexthe666/citadel/Citadel.java b/src/main/java/com/github/alexthe666/citadel/Citadel.java index 6ba4c79..5013f2f 100644 --- a/src/main/java/com/github/alexthe666/citadel/Citadel.java +++ b/src/main/java/com/github/alexthe666/citadel/Citadel.java @@ -50,7 +50,7 @@ import java.util.function.Supplier; @Mod("citadel") -@EventBusSubscriber +@EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD) public class Citadel { public static final Logger LOGGER = LogManager.getLogger("citadel"); private static final String PROTOCOL_VERSION = Integer.toString(1); @@ -81,6 +81,8 @@ public Citadel(ModContainer modContainer, IEventBus bus) { NeoForge.EVENT_BUS.register(PROXY); modContainer.registerConfig(ModConfig.Type.COMMON, ConfigHolder.SERVER_SPEC); NeoForge.EVENT_BUS.register(new CitadelEvents()); + // Register NeoForge bus events (non-mod lifecycle events) + NeoForge.EVENT_BUS.addListener(EventPriority.LOWEST, Citadel::onServerAboutToStart); } @SubscribeEvent @@ -130,7 +132,7 @@ public static void registerPayloads(RegisterPayloadHandlersEvent event) { registrar.playToServer(SyncPathReachedMessage.TYPE, SyncPathReachedMessage.CODEC, SyncPathReachedMessage::handle); } - @SubscribeEvent(priority = EventPriority.LOWEST) + // Registered manually to NeoForge.EVENT_BUS in constructor (not a mod bus event) public static void onServerAboutToStart(ServerAboutToStartEvent event) { RegistryAccess registryAccess = event.getServer().registryAccess(); VillageHouseManager.addAllHouses(registryAccess); diff --git a/src/main/java/com/github/alexthe666/citadel/client/ClientEvents.java b/src/main/java/com/github/alexthe666/citadel/client/ClientEvents.java index 8607439..75e1317 100644 --- a/src/main/java/com/github/alexthe666/citadel/client/ClientEvents.java +++ b/src/main/java/com/github/alexthe666/citadel/client/ClientEvents.java @@ -9,7 +9,7 @@ import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.neoforge.client.event.RegisterShadersEvent; -@EventBusSubscriber(Dist.CLIENT) +@EventBusSubscriber(value = Dist.CLIENT, bus = EventBusSubscriber.Bus.MOD) public class ClientEvents { @SubscribeEvent public static void registerShaders(final RegisterShadersEvent e) { diff --git a/src/main/java/com/github/alexthe666/citadel/client/gui/EntityLinkButton.java b/src/main/java/com/github/alexthe666/citadel/client/gui/EntityLinkButton.java index df1eb33..913fcdf 100644 --- a/src/main/java/com/github/alexthe666/citadel/client/gui/EntityLinkButton.java +++ b/src/main/java/com/github/alexthe666/citadel/client/gui/EntityLinkButton.java @@ -41,9 +41,17 @@ public void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float guiGraphics.pose().translate(this.getX(), this.getY(), 0); guiGraphics.pose().scale(f, f, 1); this.drawBtn(false, guiGraphics, 0, 0, lvt_5_1_, lvt_6_1_, 24, 24); - Entity model = null; - EntityType type = BuiltInRegistries.ENTITY_TYPE.get(ResourceLocation.parse(data.getEntity())); - model = renderedEntites.putIfAbsent(data.getEntity(), type.create(Minecraft.getInstance().level)); + Entity model = renderedEntites.get(data.getEntity()); + if (model == null) { + BuiltInRegistries.ENTITY_TYPE.getOptional(ResourceLocation.parse(data.getEntity())) + .ifPresent(type -> { + Entity newEntity = type.create(Minecraft.getInstance().level); + if (newEntity != null) { + renderedEntites.put(data.getEntity(), newEntity); + } + }); + model = renderedEntites.get(data.getEntity()); + } guiGraphics.enableScissor(this.getX() + Math.round(f * 4), this.getY() + Math.round(f * 4), this.getX() + Math.round(f * 20), this.getY() + Math.round(f * 20)); if (model != null) { diff --git a/src/main/java/com/github/alexthe666/citadel/client/gui/GuiBasicBook.java b/src/main/java/com/github/alexthe666/citadel/client/gui/GuiBasicBook.java index e58b97e..cfb32f8 100644 --- a/src/main/java/com/github/alexthe666/citadel/client/gui/GuiBasicBook.java +++ b/src/main/java/com/github/alexthe666/citadel/client/gui/GuiBasicBook.java @@ -255,6 +255,15 @@ private void onSwitchPage(boolean next) { refreshSpacing(); } + /** + * Override to disable the blur effect that was added in Minecraft 1.21 + * Without this override, the screen content appears blurry + */ + @Override + protected void renderBlurredBackground(float partialTick) { + // Do nothing - this prevents the blur effect from being applied + } + @Override public void render(GuiGraphics guiGraphics, int x, int y, float partialTicks) { this.mouseX = x; @@ -419,8 +428,13 @@ private void renderOtherWidgets(GuiGraphics guiGraphics, int x, int y, BookPage for (EntityRenderData data : entityRenders) { if (data.getPage() == this.currentPageCounter) { Entity model = null; - EntityType type = BuiltInRegistries.ENTITY_TYPE.get(ResourceLocation.parse(data.getEntity())); - model = renderedEntites.putIfAbsent(data.getEntity(), type.create(Minecraft.getInstance().level)); + try { + EntityType type = BuiltInRegistries.ENTITY_TYPE.get(ResourceLocation.parse(data.getEntity())); + model = renderedEntites.putIfAbsent(data.getEntity(), type.create(Minecraft.getInstance().level)); + } catch (Exception e) { + // Entity creation failed - skip rendering this entity + continue; + } if (model != null) { float scale = (float) data.getScale(); model.tickCount = Minecraft.getInstance().player.tickCount; diff --git a/src/main/java/com/github/alexthe666/citadel/client/gui/data/LinkData.java b/src/main/java/com/github/alexthe666/citadel/client/gui/data/LinkData.java index 1e992ea..8c185d6 100644 --- a/src/main/java/com/github/alexthe666/citadel/client/gui/data/LinkData.java +++ b/src/main/java/com/github/alexthe666/citadel/client/gui/data/LinkData.java @@ -8,7 +8,7 @@ public class LinkData { private int x; private int y; private int page; - private ItemStack stack; + private transient ItemStack stack; public LinkData(String linkedPage, String titleText, int x, int y, int page) { this(linkedPage, titleText, x, y, page, ItemStack.EMPTY); @@ -60,6 +60,6 @@ public void setY(int y) { } public ItemStack getDisplayItem() { - return this.stack.copy(); + return this.stack != null ? this.stack.copy() : ItemStack.EMPTY; } } From 5819e78321abddce5ceb6c994d2d58006907b7fb Mon Sep 17 00:00:00 2001 From: Alex Lee Date: Sun, 28 Dec 2025 18:59:36 +0800 Subject: [PATCH 2/7] Update rendertype_rainbow_aura shader configuration and add vertex shader --- .../shaders/core/rendertype_rainbow_aura.json | 57 ++++++++++++------- .../shaders/core/rendertype_rainbow_aura.vsh | 17 ++++++ 2 files changed, 53 insertions(+), 21 deletions(-) create mode 100644 src/main/resources/assets/citadel/shaders/core/rendertype_rainbow_aura.vsh diff --git a/src/main/resources/assets/citadel/shaders/core/rendertype_rainbow_aura.json b/src/main/resources/assets/citadel/shaders/core/rendertype_rainbow_aura.json index d49fd7a..51a0fea 100644 --- a/src/main/resources/assets/citadel/shaders/core/rendertype_rainbow_aura.json +++ b/src/main/resources/assets/citadel/shaders/core/rendertype_rainbow_aura.json @@ -1,23 +1,38 @@ { - "blend": { - "func": "add", - "srcrgb": "srcalpha", - "dstrgb": "1-srcalpha" + "blend": { + "func": "add", + "srcrgb": "srcalpha", + "dstrgb": "1-srcalpha" + }, + "vertex": "citadel:rendertype_rainbow_aura", + "fragment": "citadel:rendertype_rainbow_aura", + "attributes": ["Position", "Color", "UV0"], + "samplers": [{ "name": "Sampler0" }], + "uniforms": [ + { + "name": "ModelViewMat", + "type": "matrix4x4", + "count": 16, + "values": [ + 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0 + ] }, - "vertex": "position_color_tex", - "fragment": "citadel:rendertype_rainbow_aura", - "attributes": [ - "Position", - "Color", - "UV0" - ], - "samplers": [ - { "name": "Sampler0" } - ], - "uniforms": [ - { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, - { "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] }, - { "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }, - { "name": "GameTime", "type": "float", "count": 1, "values": [ 0.0 ] } - ] -} \ No newline at end of file + { + "name": "ProjMat", + "type": "matrix4x4", + "count": 16, + "values": [ + 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0 + ] + }, + { + "name": "ColorModulator", + "type": "float", + "count": 4, + "values": [1.0, 1.0, 1.0, 1.0] + }, + { "name": "GameTime", "type": "float", "count": 1, "values": [0.0] } + ] +} diff --git a/src/main/resources/assets/citadel/shaders/core/rendertype_rainbow_aura.vsh b/src/main/resources/assets/citadel/shaders/core/rendertype_rainbow_aura.vsh new file mode 100644 index 0000000..e1898cb --- /dev/null +++ b/src/main/resources/assets/citadel/shaders/core/rendertype_rainbow_aura.vsh @@ -0,0 +1,17 @@ +#version 150 + +in vec3 Position; +in vec4 Color; +in vec2 UV0; + +uniform mat4 ModelViewMat; +uniform mat4 ProjMat; + +out vec4 vertexColor; +out vec2 texCoord0; + +void main() { + gl_Position = ProjMat * ModelViewMat * vec4(Position, 1.0); + vertexColor = Color; + texCoord0 = UV0; +} From 40491e5db2bd0e5bae31e46a1fe59ca83728d3d3 Mon Sep 17 00:00:00 2001 From: Alex Lee Date: Sun, 28 Dec 2025 21:29:48 +0800 Subject: [PATCH 3/7] Register ClientProxy to event bus only in client environment --- src/main/java/com/github/alexthe666/citadel/Citadel.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/alexthe666/citadel/Citadel.java b/src/main/java/com/github/alexthe666/citadel/Citadel.java index 5013f2f..80b3e45 100644 --- a/src/main/java/com/github/alexthe666/citadel/Citadel.java +++ b/src/main/java/com/github/alexthe666/citadel/Citadel.java @@ -78,7 +78,10 @@ public Citadel(ModContainer modContainer, IEventBus bus) { final DeferredRegister> serializers = DeferredRegister.create(NeoForgeRegistries.BIOME_MODIFIER_SERIALIZERS, "citadel"); serializers.register(bus); serializers.register("mob_spawn_probability", SpawnProbabilityModifier::makeCodec); - NeoForge.EVENT_BUS.register(PROXY); + // Only register ClientProxy to event bus - ServerProxy has no @SubscribeEvent methods + if (FMLEnvironment.dist.isClient()) { + NeoForge.EVENT_BUS.register(PROXY); + } modContainer.registerConfig(ModConfig.Type.COMMON, ConfigHolder.SERVER_SPEC); NeoForge.EVENT_BUS.register(new CitadelEvents()); // Register NeoForge bus events (non-mod lifecycle events) From 6d6503b945ec2bbf04dfb1206e97daf81321616c Mon Sep 17 00:00:00 2001 From: Alex Lee Date: Sun, 28 Dec 2025 22:00:15 +0800 Subject: [PATCH 4/7] Refactor message registration to clarify bidirectional and client-specific handling --- .../java/com/github/alexthe666/citadel/Citadel.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/github/alexthe666/citadel/Citadel.java b/src/main/java/com/github/alexthe666/citadel/Citadel.java index 80b3e45..447ed1e 100644 --- a/src/main/java/com/github/alexthe666/citadel/Citadel.java +++ b/src/main/java/com/github/alexthe666/citadel/Citadel.java @@ -128,11 +128,16 @@ public static void doClientStuff(final FMLClientSetupEvent event) { @SubscribeEvent public static void registerPayloads(RegisterPayloadHandlersEvent event) { final PayloadRegistrar registrar = event.registrar("citadel").versioned("2.7.0").optional(); - registrar.playToServer(PropertiesMessage.TYPE, PropertiesMessage.CODEC, PropertiesMessage::handle); - registrar.playToServer(AnimationMessage.TYPE, AnimationMessage.CODEC, AnimationMessage::handle); + // PropertiesMessage is bidirectional - used by both client (GUI) and server (entity utils) + registrar.playBidirectional(PropertiesMessage.TYPE, PropertiesMessage.CODEC, PropertiesMessage::handle); + // AnimationMessage is sent from server to all clients via sendToAllPlayers + registrar.playToClient(AnimationMessage.TYPE, AnimationMessage.CODEC, AnimationMessage::handle); + // DanceJukeboxMessage is sent from client to server via sendToServer registrar.playToServer(DanceJukeboxMessage.TYPE, DanceJukeboxMessage.CODEC, DanceJukeboxMessage::handle); - registrar.playToServer(SyncePathMessage.TYPE, SyncePathMessage.CODEC, SyncePathMessage::handle); - registrar.playToServer(SyncPathReachedMessage.TYPE, SyncPathReachedMessage.CODEC, SyncPathReachedMessage::handle); + // SyncePathMessage is sent from server to specific player via sendToPlayer + registrar.playToClient(SyncePathMessage.TYPE, SyncePathMessage.CODEC, SyncePathMessage::handle); + // SyncPathReachedMessage is sent from server to specific player via sendToPlayer + registrar.playToClient(SyncPathReachedMessage.TYPE, SyncPathReachedMessage.CODEC, SyncPathReachedMessage::handle); } // Registered manually to NeoForge.EVENT_BUS in constructor (not a mod bus event) From 102f62315ee8eed102468f72a765868e95d1b847 Mon Sep 17 00:00:00 2001 From: Alex Lee Date: Mon, 29 Dec 2025 20:15:23 +0800 Subject: [PATCH 5/7] Improve entity creation logging in GuiBasicBook and EntityLinkButton --- .../citadel/client/gui/EntityLinkButton.java | 17 ++++++++++------- .../citadel/client/gui/GuiBasicBook.java | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/github/alexthe666/citadel/client/gui/EntityLinkButton.java b/src/main/java/com/github/alexthe666/citadel/client/gui/EntityLinkButton.java index 913fcdf..7eb33bf 100644 --- a/src/main/java/com/github/alexthe666/citadel/client/gui/EntityLinkButton.java +++ b/src/main/java/com/github/alexthe666/citadel/client/gui/EntityLinkButton.java @@ -1,5 +1,6 @@ package com.github.alexthe666.citadel.client.gui; +import com.github.alexthe666.citadel.Citadel; import com.github.alexthe666.citadel.client.gui.data.EntityLinkData; import com.mojang.blaze3d.platform.Lighting; import com.mojang.blaze3d.systems.RenderSystem; @@ -43,13 +44,15 @@ public void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float this.drawBtn(false, guiGraphics, 0, 0, lvt_5_1_, lvt_6_1_, 24, 24); Entity model = renderedEntites.get(data.getEntity()); if (model == null) { - BuiltInRegistries.ENTITY_TYPE.getOptional(ResourceLocation.parse(data.getEntity())) - .ifPresent(type -> { - Entity newEntity = type.create(Minecraft.getInstance().level); - if (newEntity != null) { - renderedEntites.put(data.getEntity(), newEntity); - } - }); + var optional = BuiltInRegistries.ENTITY_TYPE.getOptional(ResourceLocation.parse(data.getEntity())); + if (optional.isPresent()) { + Entity newEntity = optional.get().create(Minecraft.getInstance().level); + if (newEntity != null) { + renderedEntites.put(data.getEntity(), newEntity); + } + } else { + Citadel.LOGGER.warn("Could not find entity type for book link button: {}", data.getEntity()); + } model = renderedEntites.get(data.getEntity()); } diff --git a/src/main/java/com/github/alexthe666/citadel/client/gui/GuiBasicBook.java b/src/main/java/com/github/alexthe666/citadel/client/gui/GuiBasicBook.java index cfb32f8..671a7e1 100644 --- a/src/main/java/com/github/alexthe666/citadel/client/gui/GuiBasicBook.java +++ b/src/main/java/com/github/alexthe666/citadel/client/gui/GuiBasicBook.java @@ -432,7 +432,7 @@ private void renderOtherWidgets(GuiGraphics guiGraphics, int x, int y, BookPage EntityType type = BuiltInRegistries.ENTITY_TYPE.get(ResourceLocation.parse(data.getEntity())); model = renderedEntites.putIfAbsent(data.getEntity(), type.create(Minecraft.getInstance().level)); } catch (Exception e) { - // Entity creation failed - skip rendering this entity + Citadel.LOGGER.warn("Failed to create entity '{}' for book rendering, skipping.", data.getEntity(), e); continue; } if (model != null) { From be14e0e39a0e70d2e942b28adde51d4c2a38a773 Mon Sep 17 00:00:00 2001 From: Alex Lee Date: Mon, 29 Dec 2025 23:29:16 +0800 Subject: [PATCH 6/7] Fix default rotation speed for CitadelPatreonRenderer and update mixin configuration --- src/main/java/com/github/alexthe666/citadel/ClientProxy.java | 2 +- src/main/resources/citadel.mixins.json | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/alexthe666/citadel/ClientProxy.java b/src/main/java/com/github/alexthe666/citadel/ClientProxy.java index a417ef5..77e505f 100644 --- a/src/main/java/com/github/alexthe666/citadel/ClientProxy.java +++ b/src/main/java/com/github/alexthe666/citadel/ClientProxy.java @@ -131,7 +131,7 @@ public void playerRender(RenderPlayerEvent.Pre event) { CitadelPatreonRenderer renderer = CitadelPatreonRenderer.get(rendererName); if (renderer != null) { float distance = tag.contains("CitadelRotateDistance") ? tag.getFloat("CitadelRotateDistance") : 2F; - float speed = tag.contains("CitadelRotateSpeed") ? tag.getFloat("CitadelRotateSpeed") : 1; + float speed = tag.contains("CitadelRotateSpeed") ? tag.getFloat("CitadelRotateSpeed") : 0F; float height = tag.contains("CitadelRotateHeight") ? tag.getFloat("CitadelRotateHeight") : 1F; renderer.render(matrixStackIn, event.getMultiBufferSource(), event.getPackedLight(), event.getPartialTick(), event.getEntity(), distance, speed, height); } diff --git a/src/main/resources/citadel.mixins.json b/src/main/resources/citadel.mixins.json index d1a5fa0..118b734 100644 --- a/src/main/resources/citadel.mixins.json +++ b/src/main/resources/citadel.mixins.json @@ -5,9 +5,11 @@ "compatibilityLevel": "JAVA_17", "refmap": "citadel.refmap.json", "mixins": [ - "BlockBehaviourAccessor" + "BlockBehaviourAccessor", + "LivingEntityMixin" ], "client": [ + "client.LivingEntityRendererMixin" ], "injectors": { "defaultRequire": 1 From 1a62cbc30484cd181b50b6188c4da4379414a709 Mon Sep 17 00:00:00 2001 From: Alex Lee Date: Mon, 29 Dec 2025 23:29:27 +0800 Subject: [PATCH 7/7] Format mixin and client entries in citadel.mixins.json for consistency --- src/main/resources/citadel.mixins.json | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/main/resources/citadel.mixins.json b/src/main/resources/citadel.mixins.json index 118b734..a36b848 100644 --- a/src/main/resources/citadel.mixins.json +++ b/src/main/resources/citadel.mixins.json @@ -4,14 +4,9 @@ "package": "com.github.alexthe666.citadel.mixin", "compatibilityLevel": "JAVA_17", "refmap": "citadel.refmap.json", - "mixins": [ - "BlockBehaviourAccessor", - "LivingEntityMixin" - ], - "client": [ - "client.LivingEntityRendererMixin" - ], + "mixins": ["BlockBehaviourAccessor", "LivingEntityMixin"], + "client": ["client.LivingEntityRendererMixin"], "injectors": { "defaultRequire": 1 } -} \ No newline at end of file +}