Description
Chained Curios
A simple, vanilla-friendly mod that gives you a second layer of defense. No more choosing between your enchanted diamond chestplate and that cool-looking chainmail. Now you can wear both.
Features:
Underlayer Armor
Adds four new "underlayer" Curios slots, one for each armor type. This mod re-purposes vanilla chainmail to be worn underneath your primary armor instead of in the main armor slots. kinda like how you would in real life.
Layered Protection
The chainmail provides its full armor and enchantment benefits, stacking with your main gear. More protection is always better.
Smart Durability
The underlayer takes durability damage, but it's smart about it. If you have a primary armor piece equipped over it, the underlayer takes 60% less durability damage.
Seamless Visuals
The best part. The chainmail realistically renders only in the gaps of your outer armor. No ugly clipping or Z-fighting. It just looks right.
How to Use
- Make sure you have Forge and the Curios API for Minecraft 1.20.1 installed.
- Drop the .jar file into your
modsfolder. - Open your inventory and find the new "underlayer" slots in the Curios menu.
- Equip chainmail armor manually or by right-clicking or shift-clicking it.
Compatibility
- Outer Armor: The dynamic rendering technique is designed to work with armor from most other mods. You can wear your vanilla chainmail underlayer beneath almost any modded armor and it should render correctly. armor in the gallery is from the minecraft dungeons and armor mod
- All the Trims: The mod includes explicit support for the All the Trims mod. Armor trims will render correctly on the chainmail underlayer.
- Underlayer Armor: Please note that this mod currently only adds the underlayer functionality to vanilla Chainmail Armor. It does not enable other modded armor sets to be used as underlayers.
Technicals
This mod is designed to be lightweight and client-focused. Here's a look under the hood:
Curios Integration (
CapabilityAttacher.java&UnderlayerCurioProvider.java):- The mod subscribes to Forge's
AttachCapabilitiesEvent<ItemStack>. When the event fires for a chainmail item, we attach our ownICapabilityProvider. - This provider,
UnderlayerCurioProvider, exposes theICuriocapability. The core logic resides in theICurioimplementation:canEquipFromUse: Returnstrueto enable right-click and shift-click equipping.canEquip: Checks theSlotContextidentifier to ensure a chainmail piece can only be placed in its corresponding "underlayer_*" slot (e.g.,Items.CHAINMAIL_HELMETin"underlayer_head").getAttributeModifiers: This is key for providing armor stats. It gets the item's default attribute modifiers for its correspondingEquipmentSlotand rebuilds them with a new UUID, effectively copying the armor and armor toughness attributes to the Curio.getEquipSound: Returns the vanillaSoundEvents.ARMOR_EQUIP_CHAIN.
- The mod subscribes to Forge's
Damage & Durability Logic (
ModForgeEvents.java):- A static event handler subscribes to
LivingHurtEvent. This event is where all damage calculations happen. - Enchantment Protection: The handler gets the player's Curios inventory and iterates through the equipped items. For each chainmail curio, it calls the vanilla
EnchantmentHelper.getDamageProtection()and accumulates the value. This total is then used to calculate the damage reduction factor (1.0f - Math.min(20.0f, totalEnchantmentProtection) / 25.0f), and the event's damage amount is updated. - Durability Damage: After the damage is reduced, the final amount is used to calculate durability loss. The base durability damage is
(int) Math.max(1.0f, finalDamage / 4.0f). - Synergy: The handler then checks if the player is wearing a corresponding piece of vanilla armor. If so, the durability damage for the curio is reduced by 60% (
durabilityDamage * 0.4f). - Finally, the
ItemStack.hurtAndBreak()method is called on the curio's stack to apply the damage.
- A static event handler subscribes to
The Rendering Magic (
UnderlayerRenderer.java&ClientModEvents.java):- Registration: In the
FMLClientSetupEvent, we register an instance of ourUnderlayerRendererfor each of the four chainmail items usingCuriosRendererRegistry.register(). - The Problem: Rendering layered armor typically results in Z-fighting, where the inner and outer models clip through each other.
- The Solution (Stencil Buffering): We use a multi-pass rendering technique to solve this.
- Pass 1: The Stencil Mold: We render the outer armor first, but invisibly (
RenderSystem.colorMask(false, false, false, false)). This pass writes to the depth buffer (creating a 3D "mold") and, crucially, writes a value of1to the stencil buffer for every pixel the armor occupies. A customRenderType(armorCutoutWithCull) is used to enable back-face culling, preventing the inside of the armor from creating a messy mold. - Pass 2: The Clipped Underlayer: We then render the chainmail underlayer. However, we configure the
RenderSystemto only draw where the stencil buffer's value is not equal to1(RenderSystem.stencilFunc(GL11.GL_NOTEQUAL, 1, 0xFF)). This confines the underlayer to the 2D silhouette of the outer armor. The standard depth test against the "mold" from Pass 1 then correctly clips the underlayer in 3D space, ensuring it only appears in the gaps and underneath the outer armor.
- Pass 1: The Stencil Mold: We render the outer armor first, but invisibly (
- Chestplate Exception: The chestplate model, with its separate body and arm pieces, requires a more complex cycle. The body is rendered first (with limbs stenciled out), followed by the limbs (with the body stenciled out), ensuring a perfect composite.
- Compatibility: The renderer includes a specific call to
AllTheTrimsCompat.tryRender()to provide explicit support for rendering trims from the All the Trims mod. If that fails or the mod is not present, it falls back to the vanilla trim rendering logic.
- Registration: In the


