From e80d8a8f3401dccf7ce33fd4bd28516940865f76 Mon Sep 17 00:00:00 2001 From: austin Date: Sat, 18 Apr 2026 15:02:34 +0000 Subject: [PATCH 1/2] Fix DM/RM tools and armor crashing server on NeoForge 1.21.1 NoDurabilityItemProperties overrode durability() as a NO-OP, causing DM/RM tools and armor to be registered without a minecraft:max_damage data component. NeoForge's DataComponentUtil.wrapEncodingExceptions requires a positive value for this component, throwing: IllegalStateException: Value must be positive: 0 at ItemStack.save() on the next player tick after crafting. Fix: remove NoDurabilityItemProperties, register tools and armor with durability(Integer.MAX_VALUE). damageItem() still returns 0 in PETool, PEPickaxe, and PEArmor so durability is never actually consumed. Also adds registerArmor() to ItemDeferredRegister and switches all 12 DM/RM/Gem armor registrations from registerNoStackFireImmune to it. --- .../impl/ItemDeferredRegister.java | 20 ++++++------- .../projecte/gameObjs/registries/PEItems.java | 28 +++++++++---------- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/main/java/moze_intel/projecte/gameObjs/registration/impl/ItemDeferredRegister.java b/src/main/java/moze_intel/projecte/gameObjs/registration/impl/ItemDeferredRegister.java index 91fde6ab6..17458b71c 100644 --- a/src/main/java/moze_intel/projecte/gameObjs/registration/impl/ItemDeferredRegister.java +++ b/src/main/java/moze_intel/projecte/gameObjs/registration/impl/ItemDeferredRegister.java @@ -90,8 +90,16 @@ public ItemRegistryObject registerNoStackFireImmune(St return register(name, sup, properties -> properties.stacksTo(1).fireResistant()); } + // Use for armor items — sets a real max_damage so the minecraft:max_damage component is present. + // damageItem() in PEArmor always returns 0, so durability is never actually consumed. + public ItemRegistryObject registerArmor(String name, Function sup) { + return register(name, sup, properties -> properties.durability(Integer.MAX_VALUE).stacksTo(1).fireResistant()); + } + public ItemRegistryObject registerTool(String name, Function sup) { - return register(name, () -> sup.apply(new NoDurabilityItemProperties().stacksTo(1).fireResistant())); + // Use real durability so minecraft:max_damage component is present on the ItemStack. + // damageItem() in PETool/PEPickaxe always returns 0 so durability is never actually consumed. + return register(name, () -> sup.apply(new Item.Properties().durability(Integer.MAX_VALUE).stacksTo(1).fireResistant())); } public ItemRegistryObject register(String name, Function sup, UnaryOperator propertyModifier) { @@ -104,14 +112,4 @@ public ItemRegistryObject register(String name, Functi public ItemRegistryObject register(@NotNull String name, @NotNull Supplier sup) { return (ItemRegistryObject) super.register(name, sup); } - - private static class NoDurabilityItemProperties extends Item.Properties { - - @NotNull - @Override - public Item.Properties durability(int maxDamage) { - //NO-OP super setting durability components - return this; - } - } } \ No newline at end of file diff --git a/src/main/java/moze_intel/projecte/gameObjs/registries/PEItems.java b/src/main/java/moze_intel/projecte/gameObjs/registries/PEItems.java index 2423012e2..007ba1392 100644 --- a/src/main/java/moze_intel/projecte/gameObjs/registries/PEItems.java +++ b/src/main/java/moze_intel/projecte/gameObjs/registries/PEItems.java @@ -111,20 +111,20 @@ public class PEItems { public static final ItemRegistryObject RED_MATTER_KATAR = ITEMS.registerTool("rm_katar", properties -> new PEKatar(EnumMatterType.RED_MATTER, 4, properties)); public static final ItemRegistryObject RED_MATTER_MORNING_STAR = ITEMS.registerTool("rm_morning_star", properties -> new PEMorningStar(EnumMatterType.RED_MATTER, 4, properties)); - public static final ItemRegistryObject DARK_MATTER_HELMET = ITEMS.registerNoStackFireImmune("dm_helmet", properties -> new DMArmor(ArmorItem.Type.HELMET, properties)); - public static final ItemRegistryObject DARK_MATTER_CHESTPLATE = ITEMS.registerNoStackFireImmune("dm_chestplate", properties -> new DMArmor(ArmorItem.Type.CHESTPLATE, properties)); - public static final ItemRegistryObject DARK_MATTER_LEGGINGS = ITEMS.registerNoStackFireImmune("dm_leggings", properties -> new DMArmor(ArmorItem.Type.LEGGINGS, properties)); - public static final ItemRegistryObject DARK_MATTER_BOOTS = ITEMS.registerNoStackFireImmune("dm_boots", properties -> new DMArmor(ArmorItem.Type.BOOTS, properties)); - - public static final ItemRegistryObject RED_MATTER_HELMET = ITEMS.registerNoStackFireImmune("rm_helmet", properties -> new RMArmor(ArmorItem.Type.HELMET, properties)); - public static final ItemRegistryObject RED_MATTER_CHESTPLATE = ITEMS.registerNoStackFireImmune("rm_chestplate", properties -> new RMArmor(ArmorItem.Type.CHESTPLATE, properties)); - public static final ItemRegistryObject RED_MATTER_LEGGINGS = ITEMS.registerNoStackFireImmune("rm_leggings", properties -> new RMArmor(ArmorItem.Type.LEGGINGS, properties)); - public static final ItemRegistryObject RED_MATTER_BOOTS = ITEMS.registerNoStackFireImmune("rm_boots", properties -> new RMArmor(ArmorItem.Type.BOOTS, properties)); - - public static final ItemRegistryObject GEM_HELMET = ITEMS.registerNoStackFireImmune("gem_helmet", GemHelmet::new); - public static final ItemRegistryObject GEM_CHESTPLATE = ITEMS.registerNoStackFireImmune("gem_chestplate", GemChest::new); - public static final ItemRegistryObject GEM_LEGGINGS = ITEMS.registerNoStackFireImmune("gem_leggings", GemLegs::new); - public static final ItemRegistryObject GEM_BOOTS = ITEMS.registerNoStackFireImmune("gem_boots", GemFeet::new); + public static final ItemRegistryObject DARK_MATTER_HELMET = ITEMS.registerArmor("dm_helmet", properties -> new DMArmor(ArmorItem.Type.HELMET, properties)); + public static final ItemRegistryObject DARK_MATTER_CHESTPLATE = ITEMS.registerArmor("dm_chestplate", properties -> new DMArmor(ArmorItem.Type.CHESTPLATE, properties)); + public static final ItemRegistryObject DARK_MATTER_LEGGINGS = ITEMS.registerArmor("dm_leggings", properties -> new DMArmor(ArmorItem.Type.LEGGINGS, properties)); + public static final ItemRegistryObject DARK_MATTER_BOOTS = ITEMS.registerArmor("dm_boots", properties -> new DMArmor(ArmorItem.Type.BOOTS, properties)); + + public static final ItemRegistryObject RED_MATTER_HELMET = ITEMS.registerArmor("rm_helmet", properties -> new RMArmor(ArmorItem.Type.HELMET, properties)); + public static final ItemRegistryObject RED_MATTER_CHESTPLATE = ITEMS.registerArmor("rm_chestplate", properties -> new RMArmor(ArmorItem.Type.CHESTPLATE, properties)); + public static final ItemRegistryObject RED_MATTER_LEGGINGS = ITEMS.registerArmor("rm_leggings", properties -> new RMArmor(ArmorItem.Type.LEGGINGS, properties)); + public static final ItemRegistryObject RED_MATTER_BOOTS = ITEMS.registerArmor("rm_boots", properties -> new RMArmor(ArmorItem.Type.BOOTS, properties)); + + public static final ItemRegistryObject GEM_HELMET = ITEMS.registerArmor("gem_helmet", GemHelmet::new); + public static final ItemRegistryObject GEM_CHESTPLATE = ITEMS.registerArmor("gem_chestplate", GemChest::new); + public static final ItemRegistryObject GEM_LEGGINGS = ITEMS.registerArmor("gem_leggings", GemLegs::new); + public static final ItemRegistryObject GEM_BOOTS = ITEMS.registerArmor("gem_boots", GemFeet::new); public static final ItemRegistryObject IRON_BAND = ITEMS.register("iron_band"); public static final ItemRegistryObject BLACK_HOLE_BAND = ITEMS.registerNoStackFireImmune("black_hole_band", BlackHoleBand::new); From 74dec197b3933e4f2ecba8eea8e39f460dd7f2a8 Mon Sep 17 00:00:00 2001 From: austin Date: Sat, 18 Apr 2026 15:06:53 +0000 Subject: [PATCH 2/2] Add crash fix notice and install instructions to README --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index c1956ef6c..e829c991d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,25 @@ ![](/src/main/resources/logo.png?raw=true) +--- + +## ⚠️ Crash Fix Fork — NeoForge 1.21.1 + +This is a community fork of ProjectE that fixes a server crash introduced in PE1.1.0 on NeoForge 1.21.1. + +**The bug:** Crafting any DM/RM tool or armor (Dark Matter Pickaxe, Red Matter Sword, etc.) causes the server to crash immediately with `IllegalStateException: Value must be positive: 0`. Every player on the server is kicked and the server cannot restart until the item is removed from the player's inventory. + +**The fix:** DM/RM tools and armor are now registered with a real `max_damage` data component (required by NeoForge 1.21.1's serialization system). Durability is still never consumed — the items work exactly as intended. + +### How to install + +1. Go to the [**Releases**](../../releases) tab and download the latest `projecte-1.1.0.jar` +2. Replace the existing `ProjectE-1.21.1-PE1.1.0.jar` in your `mods/` folder with the downloaded jar +3. **Both the server and all clients must use this jar** (NeoForge requires matching mod versions) + +> Once an official fix is released by the ProjectE team, switch back to the official jar from [CurseForge](https://www.curseforge.com/minecraft/mc-mods/projecte/files). + +--- + Repository for ProjectE, a complete rewrite of EE2 (Equivalent Exchange 2) for modern Minecraft versions. Transmutation tables, collectors, condensers, flying rings, and all the other trinkets you love are here. Discover powerful alchemical tools, items, and devices. Break down unwanted items into EMC (Energy-Matter Covalence) and use that EMC to create new items.