Elemental Combat System for Minecraft
Abloom is a comprehensive combat modification that introduces an elemental resonance system with 14 unique elements. Each element has its own accumulation mechanics, special status effects, and strategic applications.
| Element | Resonance Effect | Duration |
|---|---|---|
| PHYSICAL | Physical resonance explosion, applies Rupture effect (target's armor reduced by 20%) | 12 seconds (240 ticks) |
| FIRE | Fire resonance explosion, applies Burning effect | 12 seconds (240 ticks) |
| WIND | Wind resonance explosion, applies Windswept effect. Applying any other elemental damage (except Wind) while this effect is active triggers the corresponding resonance explosion and can be triggered once every 5 seconds, and the duration of the resonance effect triggered by wind is half of its original value | 15 seconds (300 ticks) |
| WATER | Water resonance explosion, applies Wetness effect (increases target resonance accumulation by 50%) | 15 seconds (300 ticks) |
| EARTH | Earth resonance explosion, applies Stun effect (target cannot deal damage or move) | 5 seconds (100 ticks) |
| ICE | Ice resonance explosion, applies Freeze effect | 14 seconds (280 ticks) |
| ELECTRIC | Electric resonance explosion, applies Shock effect (target inflicts 20% less damage and has 20% attack speed reduction) | 14 seconds (280 ticks) |
| ENERGY | Energy resonance explosion, applies Overload effect (target's max health reduced by 15% and damage taken increased by 20%) | 14 seconds (280 ticks) |
| NATURAL | Natural resonance explosion, applies Bloom effect (reduces target's NATURAL resistance by 35% and PHYSICAL resistance by 15% and deals NATURAL damage over time) | 12 seconds (240 ticks) |
| QUANTUM | Quantum resonance explosion, applies Break effect (target's armor reduced by 100%) | 8 seconds (160 ticks) |
| ETHER | Ether resonance explosion, applies Corruption effect (reduces target's resistance to all damage types by 20% and deals ETHER damage over time) | 12 seconds (240 ticks) |
| LIGHT | Light resonance explosion, applies Dispersion effect that increases damage taken based on incoming damage element type: Physical +15%, Fire +15%, Wind +30%, Water +30%, Earth +15%, Ice +15%, Electric +30%, Energy +15%, Natural +15%, Quantum +15%, Ether +15%, Light +30%, Shadow +20%, Prismatic +30% | 14 seconds (280 ticks) |
| SHADOW | Shadow resonance explosion, applies Eclipse effect (target's max health reduced by 5% and armor reduced by 10%) | 14 seconds (280 ticks) |
| PRISMATIC | Prismatic damage does NOT accumulate resonance points. When the target has the Prism effect, prism damage converts to the stored elemental damage type. If no Prism effect is active, hitting a target with any resonance effect applies Prism effect for 40 seconds, and converts subsequent prism damage to that elemental damage type. | 40 seconds (800 ticks) |
The damage priority system resolves conflicts when multiple mods modify damage simultaneously. Modifiers are sorted by priority (highest to lowest) and called in registration order (FIFO) for equal priorities.
| Priority | Value | Description | When to Use |
|---|---|---|---|
| HIGHEST | 300 | Highest priority | For critically important modifications |
| HIGH | 200 | High priority | When processing BEFORE Abloom |
| NORMAL | 0 | Default priority | For simple modifiers |
| LOW | -100 | Low priority (Abloom uses this) | When processing AFTER most mods |
| LOWEST | -300 | Very low priority | When processing last |
finalDamage = currentDamage Γ M_effect Γ (1 β effectiveResist) Γ (1 + B_element) Γ C_crit Γ M_thresholdM_effect = SHOCK Γ OVERLOAD Γ BLOOM Γ DISPERSION | effectiveResist = (R_resist + R_mod + R_armor) β P_shredR_resist = 0.0 / 0.5 / β0.5 (base tag: ZERO / RESIST / WEAKNESS) | R_mod = {ELEMENT}_RESIST_MOD (β1 to 1)B_element = {ELEMENT}_DMG_BONUS (β1 to 1) | P_shred = {ELEMENT}_RES_SHRED (0 to 1)R_armor = sum of armor resistance components (β0.99 to 0.99) | C_crit = 1.0 or (1.0 + totalCritDamage) Γ 2.0 (multi-crit)M_threshold = baseMultiplier + resonanceFrequency Γ 0.01, where baseMultiplier = 2.00 / 2.25 / 2.50 (when triggered resonance explosion)pointsToAdd = round((baseAccum + effectiveAccumMultiplier) Γ (1 β effectiveResist))effectiveAccumMultiplier = weaponAccum Γ (1 + buildup) Γ (1 + wetnessBonus)effectiveResist is the same for both damage and accumulation β all resistance sources are combinedAbloom adds 16 custom status effects that can be applied through elemental resonance or other means:
| Effect | ID | Description | Color |
|---|---|---|---|
| Burn | abloom:burn |
Deals periodic fire damage over time | #FF5500 |
| Wetness | abloom:wetness |
Increases target resonance accumulation by 50% | #0080FF |
| Stun | abloom:stun |
Target cannot deal damage or move | #8B4513 |
| Freeze | abloom:freeze |
Immobilizes and deals periodic ice damage | #00BFFF |
| Shock | abloom:shock |
Target inflicts 20% less damage and has 20% attack speed reduction | #FF19FF |
| Break | abloom:break |
Target's armor reduced by 100% | #9400D3 |
| Rupture | abloom:rupture |
Target's armor reduced by 20% | #C0C0C0 |
| Bloom | abloom:bloom |
Reduces NATURAL resistance by 35% and PHYSICAL resistance by 15% and deals NATURAL damage over time | #32CD32 |
| Resonance Gain | abloom:resonance_gain |
Increases resonance frequency by 60 and resonance accumulation by +20% | #FFD700 |
| Overload | abloom:overload |
Target's max health reduced by 15% and damage taken increased by 20% | #FF00FF |
| Windswept | abloom:windswept |
Applying other elemental damage triggers resonance explosion | #00FFFF |
| Corruption | abloom:corruption |
Reduces resistance to all damage types by 20% and deals ETHER damage over time | #24B3A7 |
| Taunt | abloom:taunt |
Target will be attacked by hostile and neutral mobs | #9B2D30 |
| Dispersion | abloom:dispersion |
Damage taken by target increases damage taken based on incoming damage element type: Physical +15%, Fire +15%, Wind +30%, Water +30%, Earth +15%, Ice +15%, Electric +30%, Energy +15%, Natural +15%, Quantum +15%, Ether +15%, Light +30%, Shadow +20%, Prismatic +30% | #FFF1A5 |
| Eclipse | abloom:eclipse |
Target's max health reduced by 5% and armor reduced by 10% | #4B0082 |
| Critical Gain | abloom:critical_gain |
+40% crit damage | #FFD700 |
| Prism | abloom:prism |
Applied when Prism damage hits a target with an active resonance effect. Stores the converted element type so prism damage transforms into that element. | #FFFFFF |
| Fluorescence | abloom:fluorescence |
Beneficial effect stored on the attacker. When the attacker deals prismatic damage, Fluorescence is consumed and applies a corresponding Prism effect to the target, converting future prismatic damage to the stored element type. Lasts 60 seconds (1200 ticks). Obtained by killing an entity that has an active Prism effect. | #FFD700 |
| Suppression | abloom:suppression |
Reduces critical damage by 30% | #EE204D |
| Bleeding | abloom:bleeding |
Reduces speed by 25% and deals physical damage when the entity is jumping | #CC0033 |
| Reinforcement | abloom:reinforcement |
Adds 6 points to armor | #6B8BA4 |
Weapons can be registered with elemental properties. Multi-stage weapons can have up to 4 attack stages, each with its own element type and accumulation multiplier. Stages reset after cooldown based on attack speed.
// Register a 2-stage weapon
ResourceLocation swordId = ResourceLocation.fromNamespaceAndPath("mymod", "dragon_sword");
// Stage 1: Fire element with 2x accumulation
ElementalWeaponRegistry.registerBuiltinWeaponWithStage(
swordId,
1, // stage number (1-4)
ElementType.FIRE,
2.0f, // accumulation multiplier
0.15f, // crit chance (shared)
0.5f // crit damage (shared)
);
// Stage 2: Physical element with 3x accumulation
ElementalWeaponRegistry.registerBuiltinWeaponWithStage(
swordId,
2,
ElementType.PHYSICAL,
3.0f,
0.15f,
0.5f
);
For weapons that don't require multiple stages, use the simplified registration method:
// Register a simple fire staff with single-stage behavior
ResourceLocation staffId = ResourceLocation.fromNamespaceAndPath("mymod", "fire_staff");
ElementalWeaponRegistry.registerBuiltinWeapon(
staffId, // weapon ID
ElementType.FIRE, // element type
1.5f, // accumulation multiplier
0.2f, // crit chance
0.75f // crit damage
);
Abloom adds two custom attributes for critical hits:
| Attribute | ID | Range | Default | Description |
|---|---|---|---|---|
| CRIT_CHANCE | abloom:crit_chance |
-2 to 2 | 0 | Critical hit chance (-200% to 200%). Maximum is clamped to 2.0 (200%) to enable multi-crit. |
| CRIT_DMG | abloom:crit_dmg |
-10 to 10 | 0 | Critical hit damage multiplier (-1000% to 1000%). Applied additively from entity attributes and weapon values. |
Abloom supports multi-critical hits, which deal double critical damage. The total crit chance (entity attributes + weapon values, summed additively) is clamped to a maximum of 2.0 (200%). When total crit chance exceeds 100% (1.0), any excess above 1.0 gives a chance to trigger a multi-crit, which multiplies the resulting critical damage by 2x.
!!! in damage numbers, while normal crits show !!.
// Get crit chance from weapon stack
float critChance = ElementalWeaponUtils.getCritChance(stack);
// Get crit damage from weapon stack
float critDamage = ElementalWeaponUtils.getCritDamage(stack);
// Register weapon with crit values
ElementalWeaponRegistry.registerWeapon(
myItem,
ElementType.FIRE,
2.0f, // accumulation
0.25f, // 25% crit chance
0.75f // 75% crit damage
);
// Get effective element type (checks enchantment override first)
ElementType element = ElementDamageHandler.getEffectiveElementType(stack);
if (element == ElementType.FIRE) {
// Weapon has fire_aspect or flame enchantment
}
Abloom introduces a third custom attribute that controls how quickly elemental resonance accumulates:
| Attribute | ID | Range | Default | Description |
|---|---|---|---|---|
| RESONANCE_ACCUMULATION_BUILDUP | abloom:resonance_accumulation_buildup |
-1 to 1 | 0 | Multiples the accumulation multiplier. At 0: no effect (1.0x). At 1: doubles accumulation (2.0x). At -1: disables resonance buildup (0.0x). |
The attribute value is applied as a multiplier to the effective accumulation multiplier during damage processing. The formula is:
effectiveAccumMultiplier *= (1.0f + buildupAttributeValue);
| Attribute Value | Multiplier | Effect |
|---|---|---|
0.0 (default) |
1.0x | No change to accumulation |
0.5 |
1.5x | +50% to accumulation speed |
1.0 (max) |
2.0x | Doubles accumulation speed |
-0.5 |
0.5x | -50% to accumulation speed |
-1.0 (min) |
0.0x | Completely disables resonance buildup |
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
import net.minecraft.world.entity.ai.attributes.Attributes;
import com.auranite.abloom.init.AbloomModAttributes;
// On entity creation or modification
Entity entity = ...;
AttributeInstance buildupAttr = entity.getAttribute(
AbloomModAttributes.RESONANCE_ACCUMULATION_BUILDUP
);
if (buildupAttr != null) {
// Set absolute value
buildupAttr.setBaseValue(0.5); // +50% accumulation
// Or add a modifier
buildupAttr.addPermanentModifier(
new java.util.UUID(123456, 789012),
"mymod.buff.resonance_boost",
0.3,
java.util.UUID.randomUUID()
);
}
RESONANCE_ACCUMULATION_BUILDUP = 0.5 to build resonance faster, while a cursed player debuff might set it to -0.5 to slow down resonance buildup.
Weapons can have a resonance_frequency property that increases the damage multiplier when a resonance explosion is triggered. This property is configured in the weapon's datapack JSON.
| Element | Base Resonance DMG Multiplier |
|---|---|
| WIND | 250% |
| WATER | 250% |
| PHYSICAL | 225% |
| ELECTRIC | 225% |
| ENERGY | 225% |
| NATURAL | 225% |
| LIGHT | 225% |
| SHADOW | 225% |
| FIRE | 200% |
| EARTH | 200% |
| ICE | 200% |
| QUANTUM | 200% |
| ETHER | 200% |
Abloom introduces the RESONANCE_FREQUENCY_BONUS attribute that modifies the resonance frequency on the entity. This allows buffs, debuffs, or equipment to increase or decrease the resonance explosion damage.
| Attribute | ID | Range | Default | Description |
|---|---|---|---|---|
| RESONANCE_FREQUENCY_BONUS | abloom:resonance_frequency_bonus |
-500 to 500 | 0 | Adds to the weapon's resonance_frequency. Each point = 0.01 to the final multiplier (1 unit = 1% additional resonance explosion damage). |
import com.auranite.abloom.init.AbloomModAttributes;
// Add +50 resonance frequency bonus to attacker
Entity attacker = ...;
AttributeInstance rfBonus = attacker.getAttribute(
AbloomModAttributes.RESONANCE_FREQUENCY_BONUS
);
if (rfBonus != null) {
rfBonus.setBaseValue(50); // +50 resonance frequency
}
// Remove resonance frequency bonus
if (rfBonus != null) {
rfBonus.setBaseValue(0);
}
RESONANCE_FREQUENCY_BONUS = +100 for 30 seconds, boosting LIGHT resonance from 225% to 325% damage. A debuff could set it to -50 to weaken resonance explosions.
Abloom adds 14 new attributes that directly modify damage for each element type. Each attribute has a range of -1.0 to 1.0, representing -100% to +100% damage modifier.
| Attribute | ID | Range | Default | Element |
|---|---|---|---|---|
| FIRE_DMG_BONUS | abloom:fire_dmg_bonus |
-1 to 1 | 0 | FIRE |
| PHYSICAL_DMG_BONUS | abloom:physical_dmg_bonus |
-1 to 1 | 0 | PHYSICAL |
| WIND_DMG_BONUS | abloom:wind_dmg_bonus |
-1 to 1 | 0 | WIND |
| EARTH_DMG_BONUS | abloom:earth_dmg_bonus |
-1 to 1 | 0 | EARTH |
| WATER_DMG_BONUS | abloom:water_dmg_bonus |
-1 to 1 | 0 | WATER |
| ICE_DMG_BONUS | abloom:ice_dmg_bonus |
-1 to 1 | 0 | ICE |
| ELECTRIC_DMG_BONUS | abloom:electric_dmg_bonus |
-1 to 1 | 0 | ELECTRIC |
| ENERGY_DMG_BONUS | abloom:energy_dmg_bonus |
-1 to 1 | 0 | ENERGY |
| NATURAL_DMG_BONUS | abloom:natural_dmg_bonus |
-1 to 1 | 0 | NATURAL |
| QUANTUM_DMG_BONUS | abloom:quantum_dmg_bonus |
-1 to 1 | 0 | QUANTUM |
| ETHER_DMG_BONUS | abloom:ether_dmg_bonus |
-1 to 1 | 0 | ETHER |
| LIGHT_DMG_BONUS | abloom:light_dmg_bonus |
-1 to 1 | 0 | LIGHT |
| SHADOW_DMG_BONUS | abloom:shadow_dmg_bonus |
-1 to 1 | 0 | SHADOW |
| PRISMATIC_DMG_BONUS | abloom:prismatic_dmg_bonus |
-1 to 1 | 0 | PRISMATIC |
Each attribute value is applied as a multiplier to the final damage for that specific element. The formula is:
finalDamage *= (1.0f + elementDmgBonusValue);
// Example: fire_dmg_bonus = 0.3 β finalDamage *= 1.3 (+30% fire damage)
// Example: ice_dmg_bonus = -0.5 β finalDamage *= 0.5 (-50% ice damage)
import com.auranite.abloom.init.AbloomModAttributes;
// Set fire damage bonus on an entity
Entity entity = ...;
AttributeInstance fireBonus = entity.getAttribute(
AbloomModAttributes.FIRE_DMG_BONUS
);
if (fireBonus != null) {
fireBonus.setBaseValue(0.5); // +50% fire damage
}
// Set multiple element bonuses
AttributeInstance iceBonus = entity.getAttribute(
AbloomModAttributes.ICE_DMG_BONUS
);
if (iceBonus != null) {
iceBonus.setBaseValue(-0.3); // -30% ice damage (vulnerability)
}
FIRE_DMG_BONUS = 0.25 for 60 seconds, while a cursed armor set could apply ICE_DMG_BONUS = -0.2 to reduce ice damage taken.
Abloom adds 14 new attributes that directly modify elemental resistance for each element type. Each attribute has a range of -1.0 to 1.0, representing Β±100% resistance modifier.
| Attribute | ID | Range | Default | Element |
|---|---|---|---|---|
| FIRE_RESIST_MOD | abloom:fire_resist_mod |
-1 to 1 | 0 | FIRE |
| PHYSICAL_RESIST_MOD | abloom:physical_resist_mod |
-1 to 1 | 0 | PHYSICAL |
| WIND_RESIST_MOD | abloom:wind_resist_mod |
-1 to 1 | 0 | WIND |
| EARTH_RESIST_MOD | abloom:earth_resist_mod |
-1 to 1 | 0 | EARTH |
| WATER_RESIST_MOD | abloom:water_resist_mod |
-1 to 1 | 0 | WATER |
| ICE_RESIST_MOD | abloom:ice_resist_mod |
-1 to 1 | 0 | ICE |
| ELECTRIC_RESIST_MOD | abloom:electric_resist_mod |
-1 to 1 | 0 | ELECTRIC |
| ENERGY_RESIST_MOD | abloom:energy_resist_mod |
-1 to 1 | 0 | ENERGY |
| NATURAL_RESIST_MOD | abloom:natural_resist_mod |
-1 to 1 | 0 | NATURAL |
| QUANTUM_RESIST_MOD | abloom:quantum_resist_mod |
-1 to 1 | 0 | QUANTUM |
| ETHER_RESIST_MOD | abloom:ether_resist_mod |
-1 to 1 | 0 | ETHER |
| LIGHT_RESIST_MOD | abloom:light_resist_mod |
-1 to 1 | 0 | LIGHT |
| SHADOW_RESIST_MOD | abloom:shadow_resist_mod |
-1 to 1 | 0 | SHADOW |
| PRISMATIC_RESIST_MOD | abloom:prismatic_resist_mod |
-1 to 1 | 0 | PRISMATIC |
Each attribute value is added to the base resistance value from the target's elemental tags. The formula is:
effectiveResist = baseResist + resistModValue;
damageMultiplier = 1.0 - effectiveResist;
// Example: baseResist = 0.5 (50% resist), resistMod = -0.3 β effectiveResist = 0.2 β multiplier = 0.8 (+60% damage taken)
// Example: baseResist = 0.0, resistMod = 0.4 β effectiveResist = 0.4 β multiplier = 0.6 (+40% resistance)
import com.auranite.abloom.init.AbloomModAttributes;
// Set fire resistance modifier on an entity
Entity entity = ...;
AttributeInstance fireResist = entity.getAttribute(
AbloomModAttributes.FIRE_RESIST_MOD
);
if (fireResist != null) {
fireResist.setBaseValue(0.3); // +30% fire resistance
}
// Reduce ice resistance (make entity more vulnerable)
AttributeInstance iceResist = entity.getAttribute(
AbloomModAttributes.ICE_RESIST_MOD
);
if (iceResist != null) {
iceResist.setBaseValue(-0.2); // -20% ice resistance
}
Abloom adds 14 new attributes that shred (reduce) the target's effective resistance. Each attribute has a range of 0 to 1, representing 0% to 100% resistance shred.
| Attribute | ID | Range | Default | Element |
|---|---|---|---|---|
| FIRE_RES_SHRED | abloom:fire_res_shred |
0 to 1 | 0 | FIRE |
| PHYSICAL_RES_SHRED | abloom:physical_res_shred |
0 to 1 | 0 | PHYSICAL |
| WIND_RES_SHRED | abloom:wind_res_shred |
0 to 1 | 0 | WIND |
| EARTH_RES_SHRED | abloom:earth_res_shred |
0 to 1 | 0 | EARTH |
| WATER_RES_SHRED | abloom:water_res_shred |
0 to 1 | 0 | WATER |
| ICE_RES_SHRED | abloom:ice_res_shred |
0 to 1 | 0 | ICE |
| ELECTRIC_RES_SHRED | abloom:electric_res_shred |
0 to 1 | 0 | ELECTRIC |
| ENERGY_RES_SHRED | abloom:energy_res_shred |
0 to 1 | 0 | ENERGY |
| NATURAL_RES_SHRED | abloom:natural_res_shred |
0 to 1 | 0 | NATURAL |
| QUANTUM_RES_SHRED | abloom:quantum_res_shred |
0 to 1 | 0 | QUANTUM |
| ETHER_RES_SHRED | abloom:ether_res_shred |
0 to 1 | 0 | ETHER |
| LIGHT_RES_SHRED | abloom:light_res_shred |
0 to 1 | 0 | LIGHT |
| SHADOW_RES_SHRED | abloom:shadow_res_shred |
0 to 1 | 0 | SHADOW |
| PRISMATIC_RES_SHRED | abloom:prismatic_res_shred |
0 to 1 | 0 | PRISMATIC |
Each attribute value is subtracted from the effective resistance, reducing it directly. The formula is:
effectiveResist = (R_resist + R_mod + R_armor) β resShredValue;
// Example: effectiveResist = 0.5 β 0.3 = 0.2 (20% resist instead of 50% β 80% damage taken)
import com.auranite.abloom.init.AbloomModAttributes;
// Set fire resistance shred on an attacker
Entity attacker = ...;
AttributeInstance fireShred = attacker.getAttribute(
AbloomModAttributes.FIRE_RES_SHRED
);
if (fireShred != null) {
fireShred.setBaseValue(0.3); // 30% fire resistance shred
}
// Reduce target's ice resistance by 50%
AttributeInstance iceShred = attacker.getAttribute(
AbloomModAttributes.ICE_RES_SHRED
);
if (iceShred != null) {
iceShred.setBaseValue(0.5); // 50% ice resistance shred
}
FIRE_RES_SHRED = 0.3 reduces any fire resistance the target has by 0.3.
Abloom supports overriding a weapon's elemental damage type through enchantments. This allows weapons to deal different elements based on enchantments like fire_aspect or flame, without requiring custom enchantment classes.
The damage handler checks all enchantments on the attacker's main hand and offhand weapons before checking weapon registration or datapack configs. If a matching enchantment is found, its mapped ElementType overrides the weapon's default element. The mapping is stored in a public static final ConcurrentHashMap in ElementDamageHandler, making it directly accessible for other mods to extend.
| Enchantment ID | Mapped Element | Type |
|---|---|---|
minecraft:fire_aspect |
FIRE | Vanilla enchantment (sword) |
minecraft:flame |
FIRE | Vanilla enchantment (bow) |
Other mods can register their custom enchantments to map to Abloom elements by directly adding entries to the public ENCHANTMENT_ELEMENT_MAP in ElementDamageHandler. Since the map is a public static final ConcurrentHashMap, no reflection is needed.
package com.example.mymod;
import com.auranite.abloom.handler.ElementDamageHandler;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
public class MyModEnchantments {
// Register your custom enchantment normally
public static final DeferredRegister ENCHANTMENTS =
DeferredRegister.create(ForgeRegistries.ENCHANTMENTS, "mymod");
public static final RegistryObject ICE_ASPECT =
ENCHANTMENTS.register("ice_aspect", () -> new IceAspectEnchantment());
public static final RegistryObject ELECTRIC_ASPECT =
ENCHANTMENTS.register("electric_aspect", () -> new ElectricAspectEnchantment());
/**
* Called during mod initialization to register enchantment-to-element mappings.
* Directly accesses Abloom's public ENCHANTMENT_ELEMENT_MAP (ConcurrentHashMap).
*/
public static void registerEnchantmentMappings() {
// Map custom enchantments to element types
ResourceLocation iceAspectId = ResourceLocation.fromNamespaceAndPath("mymod", "ice_aspect");
ElementDamageHandler.ENCHANTMENT_ELEMENT_MAP.put(
iceAspectId,
com.auranite.abloom.util.ElementType.ICE
);
ResourceLocation electricAspectId = ResourceLocation.fromNamespaceAndPath("mymod", "electric_aspect");
ElementDamageHandler.ENCHANTMENT_ELEMENT_MAP.put(
electricAspectId,
com.auranite.abloom.util.ElementType.ELECTRIC
);
// Example: Map a thunder enchantment to ELECTRIC
ResourceLocation thunderId = ResourceLocation.fromNamespaceAndPath("mymod", "thunder_strike");
ElementDamageHandler.ENCHANTMENT_ELEMENT_MAP.put(
thunderId,
com.auranite.abloom.util.ElementType.ELECTRIC
);
}
}
// Deal elemental damage
ElementDamageHandler.dealElementDamage(target, ElementType.FIRE, 10.0f);
// Deal with custom accumulation multiplier
ElementDamageHandler.dealElementDamage(target, ElementType.FIRE, 10.0f, 2.0f, attacker);
// Deal with specific accumulation points
ElementDamageHandler.dealElementDamage(target, ElementType.FIRE, 10.0f, 50);
// Instant damage (bypasses some modifiers)
ElementDamageHandler.applyElementalDamageInstant(target, source, ElementType.FIRE, 10.0f, 1.0f);
// Add accumulation points
ElementDamageHandler.addElementPoints(entity, ElementType.FIRE, 25);
// Get current points
int points = ElementDamageHandler.getElementPoints(entity, ElementType.FIRE);
// Reset specific element
ElementDamageHandler.resetElementPoints(entity, ElementType.FIRE);
// Reset all elements
ElementDamageHandler.resetAllElementPoints(entity);
// Get progress (0-100%)
int progress = ElementDamageHandler.getAccumulationProgress(entity, ElementType.FIRE);
// Register projectile by entity type
ElementalProjectileRegistry.registerProjectile(EntityType.ARROW, ElementType.FIRE, 1.5f);
// Register by class
ElementalProjectileRegistry.registerProjectileByClass(
MyCustomProjectile.class,
ElementType.ICE,
2.0f
);
// Check if elemental
boolean isElemental = ElementalProjectileRegistry.isElementalProjectile(projectile);
// Get element from projectile
Optional<ElementType> element = ElementalProjectileRegistry.getElementForEntity(projectile);
// Create and launch elemental projectile
Arrow projectile = ElementalProjectileRegistry.createAndLaunchElementalProjectile(
level,
shooter,
EntityType.ARROW,
1.5f, // velocity
0.1f // inaccuracy
);
// Force specific element (overrides shooter's weapon)
Arrow projectile = ElementalProjectileRegistry.createElementalProjectileWithOverride(
level,
shooter,
EntityType.ARROW,
ElementType.FIRE, // forced element
1.5f,
0.1f
);
// Enable/disable inheriting element from shooter (default: true)
ElementalProjectileRegistry.setInheritElementFromShooter(true);
// Register armor with single resistance
ArmorResistanceRegistry.registerArmor(myArmor, ElementType.FIRE, 0.3f);
// Register with multiple resistances
Map<ElementType, Float> resistances = Map.of(
ElementType.FIRE, 0.3f,
ElementType.WATER, 0.2f,
ElementType.ICE, 0.4f
);
ArmorResistanceRegistry.registerArmor(myArmor, resistances);
// Low-level component API
ItemStack resistantStack = ElementalResistanceComponent.withResistance(
stack,
ElementType.FIRE,
0.3f
);
// Get resistance value
float fireRes = ElementalResistanceComponent.getResistance(stack, ElementType.FIRE);
// Get all resistances
Map<ElementType, Float> allResistances = ElementalResistanceComponent.getAllResistances(stack);
// Get entity resistance
ElementResistanceManager.Resistance resistance =
ElementResistanceManager.getResistance(entity, ElementType.FIRE);
// Check if has resistance
boolean hasResistance = ElementResistanceManager.hasResistanceFor(entity, ElementType.FIRE);
// Check if weak to element
boolean isWeak = ElementResistanceManager.isWeakness(entity, ElementType.FIRE);
// Check if immune
boolean isImmune = ElementResistanceManager.isImmune(entity, ElementType.FIRE);
// Calculate reduced damage
float reducedDamage = ElementResistanceManager.calculateReducedDamage(
entity,
ElementType.FIRE,
10.0f
);
// Calculate accumulation points (takes resistance into account)
int points = ElementResistanceManager.calculateAccumulationPoints(
entity,
ElementType.FIRE,
10
);
// Check if damage numbers enabled
boolean enabled = AbloomConfig.areDamageNumbersEnabled();
// Check if status texts enabled
boolean statusEnabled = AbloomConfig.areStatusTextsEnabled();
// Spawn damage number
ElementDamageDisplayManager displayManager = new ElementDamageDisplayManager();
displayManager.spawnDamageNumber(entity, 10.5f, ElementType.FIRE);
// Spawn status text
displayManager.spawnStatusText(
entity,
Component.translatable("elemental.tooltip.overheating"),
0xFF5500
);
Register damage modifiers with priorities to integrate with Abloom's damage pipeline:
// Register modifier with explicit priority
DamageModificationManager.registerModifier(myModifier, 200); // HIGH - before Abloom
DamageModificationManager.registerModifier(myModifier, -100); // LOW - after Abloom
// Register with default priority (0 = NORMAL)
DamageModificationManager.registerModifier(myModifier);
// Process damage manually
float highPriorityDamage = DamageModificationManager.processHighPriorityDamage(
target,
source,
baseDamage
);
float lowPriorityDamage = DamageModificationManager.processLowPriorityDamage(
target,
source,
currentDamage
);
// Debug: get registered modifier count
int count = DamageModificationManager.getRegisteredModifierCount();
Use predefined tags to register mob resistances in datapacks:
// Available tag keys
Tags.FIRE_RESISTANCE Tags.FIRE_WEAKNESS
Tags.WATER_RESISTANCE Tags.WATER_WEAKNESS
Tags.EARTH_RESISTANCE Tags.EARTH_WEAKNESS
Tags.WIND_RESISTANCE Tags.WIND_WEAKNESS
Tags.ICE_RESISTANCE Tags.ICE_WEAKNESS
Tags.ELECTRIC_RESISTANCE Tags.ELECTRIC_WEAKNESS
Tags.PHYSICAL_RESISTANCE Tags.PHYSICAL_WEAKNESS
Tags.NATURAL_RESISTANCE Tags.NATURAL_WEAKNESS
Tags.QUANTUM_RESISTANCE Tags.QUANTUM_WEAKNESS
Tags.ETHER_RESISTANCE Tags.ETHER_WEAKNESS
Tags.LIGHT_RESISTANCE Tags.LIGHT_WEAKNESS
Tags.SHADOW_RESISTANCE Tags.SHADOW_WEAKNESS
package com.example.mymod;
import com.auranite.abloom.*;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.Rarity;
public class MyModElements {
public static final Item DRAGON_SWORD = new Item(new Item.Properties().rarity(Rarity.RARE));
public static final Item ICE_BOW = new Item(new Item.Properties().rarity(Rarity.RARE));
public static final Item IRON_CHESTPLATE = new Item(new Item.Properties().rarity(Rarity.COMMON));
public static void init() {
// Register elemental weapons
registerElementalWeapons();
// Register armor resistances
registerArmorResistances();
// Register projectiles
registerProjectiles();
}
private static void registerElementalWeapons() {
// Dragon sword: fire damage with 3x accumulation, 20% crit chance, 60% crit damage
ElementalWeaponRegistry.registerBuiltinWeapon(
DRAGON_SWORD,
ElementType.FIRE,
3.0f,
0.2f,
0.6f
);
// Ice bow: ice damage with 2x accumulation
ElementalWeaponRegistry.registerBuiltinWeapon(
ICE_BOW,
ElementType.ICE,
2.0f,
0.05f,
0.5f
);
}
private static void registerArmorResistances() {
// Iron chestplate: 30% fire resistance
ArmorResistanceRegistry.registerArmor(
IRON_CHESTPLATE,
ElementType.FIRE,
0.3f
);
}
private static void registerProjectiles() {
// Fireball projectiles: fire-elemental
ElementalProjectileRegistry.registerProjectile(
EntityType.FIREBALL,
ElementType.FIRE,
1.5f
);
// Arrows inherit element from shooter's weapon
ElementalProjectileRegistry.setInheritElementFromShooter(true);
}
}
/reload when using datapacks during development-0.99 and 0.99your_datapack.zip
βββ data
βββ abloom
βββ damage_type/ # Custom damage types (optional)
βββ elemental_weapons/ # Elemental weapon configurations
βββ armor_resistances/ # Armor resistance configurations
βββ tags
βββ entity_type
βββ element_resistance/ # Mob elemental properties
βββ fire/
β βββ resistance.json
β βββ weakness.json
βββ [other elements]/
Weapons can be configured with or without attack stages. Multi-stage weapons deal different element types and accumulation values per hit, while single-element weapons maintain consistent behavior.
Weapons can have multiple attack stages with different elements and accumulation multipliers:
{
"item": "abloom:fire_stick",
"stages": {
"1": {
"element": "PHYSICAL",
"accumulation_multiplier": 10.0
},
"2": {
"element": "PHYSICAL",
"accumulation_multiplier": 10.0
},
"3": {
"element": "FIRE",
"accumulation_multiplier": 15.0
},
"4": {
"element": "FIRE",
"accumulation_multiplier": 35.0
}
},
"base_element": "FIRE",
"crit_chance": 0.5,
"crit_damage": 1.0,
"resonance_frequency": 125
}
Fields:
item: Item ID (namespace:item_id)stages: Attack stages with element type and accumulation multiplier
element: Element type for this stage (FIRE, WATER, ICE, etc.)accumulation_multiplier: How much resonance points this stage addsbase_element: Default element type of the weaponcrit_chance: Critical hit chance (0.0 to 1.0)crit_damage: Critical hit damage multiplier (1.0 = 100% extra damage)resonance_frequency: Resonance frequency that increases resonance explosion damage multiplier (1 unit = 0.01 multiplier, e.g. 125 β +125% resonance explosion damage)Example Breakdown: The fire_stick example shows a 4-stage weapon:
For simpler weapons that always deal the same element type without stage progression:
{
"item": "abloom:water_blade",
"base_element": "WATER",
"accumulation_multiplier": 12.0,
"crit_chance": 0.3,
"crit_damage": 0.8,
"resonance_frequency": 150
}
Fields for Single-Element Weapons:
item: Item ID (namespace:item_id)base_element: Element type for all attacks (required)accumulation_multiplier: Resonance points added per hit (required when no stages)crit_chance: Critical hit chance (optional, defaults to 0.0)crit_damage: Critical hit damage multiplier (optional, defaults to 0.0)resonance_frequency: Resonance frequency that increases resonance explosion damage multiplier (1 unit = 0.01 multiplier, e.g. 150 β +150% resonance explosion damage)stages is present, the accumulation_multiplier field at the root level is ignored. Use stages for complex weapons with evolving damage patterns, or omit stages for consistent single-element weapons.
{
"item": "minecraft:leather_helmet",
"resistances": {
"ELECTRIC": 0.02,
"ICE": 0.01
}
}
// data/abloom/tags/entity_type/element_resistance/fire/resistance.json
{
"replace": false,
"values": [
"minecraft:blaze",
"minecraft:magma_cube",
"minecraft:wither",
"minecraft:ender_dragon"
]
}
// data/abloom/tags/entity_type/element_resistance/fire/weakness.json
{
"replace": false,
"values": [
"minecraft:snow_golem",
"minecraft:dolphin",
"minecraft:zombie",
"minecraft:zombie_villager"
]
}
.minecraft/saves/[worldname]/datapacks//reload commandLoaded X elemental weapon configurations from datapacksLoaded X armor resistance configurations from datapacksminecraft:zombie)Abloom supports loading custom elemental types from datapacks. Custom elements extend the elemental system beyond the 14 built-in types, allowing mod developers and players to create new elements with unique properties, resonance effects, and visual representations.
your_mod_or_datapack/
βββ data
βββ your_mod_id
βββ elemental_types/ # Custom element definitions
βββ your_element.json
Each custom element is defined in a JSON file with the following structure:
{
"element_id": "yourmod:custom_element",
"override_damage_types": ["yourmod:custom_element_damage", "minecraft:generic"],
"color": "0x2B004C",
"element_translation_key": "element.yourmod.custom",
"resonance_translation_key": "resonance.yourmod.custom",
"base_element": "FIRE",
"can_resonance_accumulation": true,
"resonance_dmg_multiplier": 2.0,
"dispersion_bonus": 0.25,
"resonance_effect": {
"effect": "yourmod:custom_resonance_effect",
"config": {
"duration": 100,
"amplifier": 0
}
},
"resonance_display_effect": "yourmod:custom_effect"
}
| Field | Type | Required | Description |
|---|---|---|---|
element_id |
ResourceLocation | Yes | Unique identifier for the element (e.g., yourmod:void) |
override_damage_types |
Array<ResourceLocation> | No | List of damage types to override when this element deals damage |
color |
Integer or Hex String | No | Element color in decimal (16777215) or hex format (0xFFFFFF). Defaults to white (0xFFFFFF) |
element_translation_key |
String | No | Translation key for element name (e.g., element.yourmod.custom). Falls back to element ID path if not provided |
resonance_translation_key |
String | No | Translation key for resonance status text. Falls back to default message if not provided |
can_resonance_accumulation |
Boolean | No | Whether this element can accumulate resonance points. Defaults to true |
resonance_dmg_multiplier |
Double | No | Multiplier for resonance explosion damage. Formula: 2.0 Γ resonance_dmg_multiplier + resonanceFrequency Γ 0.01. Defaults to 1.0 |
dispersion_bonus |
Float | No | Damage bonus multiplier when the target has the DISPERSION effect. Applied as damageMultiplier *= 1.0f + dispersionBonus. For example, 0.25 gives +25% damage. Defaults to 0.0 (no bonus) |
base_element |
String | No | Specifies the base element for damage bonus attributes and threshold multipliers. When set, the custom element uses the base element's attributes ({element}_dmg_bonus, {element}_resist_mod, {element}_res_shred). If resonance_dmg_multiplier is not specified, it defaults to the base element's threshold multiplier. For example, "FIRE" makes the custom element use fire_dmg_bonus and defaults resonance_dmg_multiplier to 2.0 (FIRE's threshold). Defaults to null (uses own attributes, resonance_dmg_multiplier defaults to 1.0) |
resonance_effect |
Object | No | Resonance effect applied at 100 accumulation points. See below for structure |
resonance_display_effect |
ResourceLocation | No | MobEffect ID used for resonance icon rendering in the UI (e.g., yourmod:custom_effect). If not set, the resonance_effect.effect is used as the display icon. Defaults to null |
The resonance_effect field defines the MobEffect applied when the element reaches 100 accumulation points:
"resonance_effect": {
"effect": "yourmod:custom_resonance_effect",
"config": {
"duration": 100,
"amplifier": 0
}
}
| Field | Type | Description |
|---|---|---|
effect |
ResourceLocation | MobEffect to apply (e.g., yourmod:custom_effect) |
config.duration |
Integer | Effect duration in ticks (must be positive) |
config.amplifier |
Integer | Effect amplifier level (0 = level I, 1 = level II, etc.) |
Custom elements support translation keys for localization. Add entries to your mod's language file:
# en_us.json
"element.yourmod.custom": "Custom Element"
"resonance.yourmod.custom": "Custom Resonance Explosion!"
# ru_ru.json
"element.yourmod.custom": "Π‘ΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΡΠΉ ΠΠ»Π΅ΠΌΠ΅Π½Ρ"
"resonance.yourmod.custom": "ΠΠ·ΡΡΠ² Π Π΅Π·ΠΎΠ½Π°Π½ΡΠ°!"
Custom elements can be used through the IElementalType interface, which is implemented by both built-in ElementType enum values and custom CustomElementType records.
import com.auranite.abloom.util.IElementalType;
import com.auranite.abloom.util.ElementType;
// Lookup any elemental type (built-in or custom)
Optional<? extends IElementalType> customType = IElementalType.byName("VOID");
if (customType.isPresent()) {
IElementalType type = customType.get();
// Use with elemental damage API
ElementDamageHandler.dealElementDamage(target, type, 10.0f);
}
// Lookup by damage type ID (e.g., "void_dmg")
Optional<? extends IElementalType> type = IElementalType.byDamageTypeId("void_dmg");
if (type.isPresent()) {
// Use with elemental API
}
IElementalType type = ...;
// Check if custom
if (type.isCustom()) {
// Access custom element data
Optional<CustomElementData> data = CustomElementRegistry.getData(type);
if (data.isPresent()) {
CustomElementData elementData = data.get();
int color = elementData.color();
double multiplier = elementData.resonanceDmgMultiplier();
// Access resonance effect config
if (elementData.resonanceEffect() != null) {
CustomElementData.ResonanceEffectConfig resonance = elementData.resonanceEffect();
ResourceLocation effectId = resonance.effect();
int duration = resonance.duration();
}
}
}
// Get display name (works for both built-in and custom)
String displayName = type.getDisplayName();
// Get damage type ID
String damageTypeId = type.damageTypeId();
import com.auranite.abloom.handler.ElementDamageHandler;
import com.auranite.abloom.util.IElementalType;
// Method 1: By name
Optional<? extends IElementalType> voidType = IElementalType.byName("VOID");
voidType.ifPresent(type -> {
ElementDamageHandler.dealElementDamage(target, type, 15.0f, 2.0f, attacker);
});
// Method 2: From CustomElementRegistry
Optional<CustomElementData> data = CustomElementRegistry.byElementId(ResourceLocation.tryParse("yourmod:void"));
data.ifPresent(elementData -> {
IElementalType type = ElementType.getCustomTypeByName(elementData.getElementName()).orElse(null);
if (type != null) {
ElementDamageHandler.dealElementDamage(target, type, 15.0f);
}
});
import com.auranite.abloom.registries.CustomElementRegistry;
import com.auranite.abloom.datapack.CustomElementData;
// Get custom element data
Optional<CustomElementData> data = CustomElementRegistry.getData(type);
if (data.isPresent()) {
CustomElementData elementData = data.get();
// Check if can accumulate resonance
if (elementData.canResonanceAccumulation()) {
// Element supports resonance
}
// Get resonance multiplier
float multiplier = CustomElementRegistry.getResonanceMultiplier(type);
// Get base element (if set)
String baseElement = CustomElementRegistry.getBaseElement(type);
if (baseElement != null) {
// This element uses base element's attributes and threshold multiplier
// e.g., "FIRE" β uses fire_dmg_bonus, fire_resist_mod, FIRE threshold (2.0)
}
// Get resonance effect config
Optional<CustomElementData.ResonanceEffectConfig> resonanceEffect =
CustomElementRegistry.getResonanceEffectConfig(type);
if (resonanceEffect.isPresent()) {
CustomElementData.ResonanceEffectConfig config = resonanceEffect.get();
// Apply resonance effect to target
target.addEffect(new MobEffectInstance(
BuiltInRegistries.MOB_EFFECT.getOptional(config.effect()).orElse(null),
config.duration(),
config.amplifier(),
false,
true
));
}
}
Colors support both decimal and hex format:
// Decimal format
"color": 2891628
// Hex format (recommended for readability)
"color": "0x2B004C"
type.isCustom() to check if an element is custom before accessing custom-specific APIsCustomElementRegistry.getResonanceEffectConfig(), not through RESONANCE_EFFECT_MAPgetActiveResonanceType() checks custom elements by their resonance effect instanceIElementalType.byName() or IElementalType.byDamageTypeId() for lookup β these handle both built-in and custom typestype.isCustom() before accessing custom element-specific methodsnamespace:name format/reload during development to ensure they load correctlyComplete example of a void element definition:
{
"element_id": "yourmod:void",
"override_damage_types": ["yourmod:void_damage", "minecraft:generic"],
"color": "0x2B004C",
"element_translation_key": "element.yourmod.void",
"resonance_translation_key": "resonance.yourmod.void",
"can_resonance_accumulation": true,
"resonance_dmg_multiplier": 2.5,
"dispersion_bonus": 0.30,
"resonance_effect": {
"effect": "yourmod:void_resonance",
"config": {
"duration": 200,
"amplifier": 1
}
},
"resonance_display_effect": "yourmod:void_resonance"
}
With corresponding translation entries:
// en_us.json
{
"element.yourmod.void": "Void",
"resonance.yourmod.void": "Void Resonance Explosion!",
"effect.yourmod.void_resonance": "Void Resonance"
}
// ru_ru.json
{
"element.yourmod.void": "ΠΡΡΡΠΎΡΠ°",
"resonance.yourmod.void": "ΠΠ·ΡΡΠ² ΠΡΡΡΠΎΡΡ!",
"effect.yourmod.void_resonance": "Π Π΅Π·ΠΎΠ½Π°Π½Ρ ΠΡΡΡΠΎΡΡ"
}
A themed "Blue Fire" element that uses FIRE's attributes, but has its own custom resonance effect:
{
"element_id": "yourmod:blue_fire",
"color": "0x4488FF",
"element_translation_key": "element.yourmod.blue_fire",
"base_element": "FIRE",
"resonance_dmg_multiplier": 1.5,
"resonance_effect": {
"effect": "yourmod:blue_burn",
"config": {
"duration": 240,
"amplifier": 0
}
},
"resonance_display_effect": "yourmod:blue_burn"
}
What this does:
fire_dmg_bonus attribute (not blue_fire_dmg_bonus)fire_resist_mod and fire_res_shred attributesresonance_dmg_multiplier = 1.5 (custom, overrides FIRE's default 2.0)resonance_dmg_multiplier (1.5) and resonance_effect (blue_burn)1.5 (blue_fire) + frequencyBonusIf resonance_dmg_multiplier is omitted, it defaults to the base element's threshold multiplier:
{
"element_id": "yourmod:blue_fire",
"color": "0x4488FF",
"element_translation_key": "element.yourmod.blue_fire",
"base_element": "FIRE",
"resonance_effect": {
"effect": "yourmod:blue_burn",
"config": {
"duration": 240,
"amplifier": 0
}
}
}
What this does:
fire_dmg_bonus attributefire_resist_mod and fire_res_shred attributesresonance_dmg_multiplier defaults to 2.0 (FIRE's threshold multiplier)resonance_effect (blue_burn)2.0 (FIRE default) + frequencyBonusCustomElementRegistry.loadFromDatapacks() called from AbloomMod.setup(). No manual registration is required β just place your JSON files in the correct directory structure and they will be available at runtime.
base_element field is useful for themed elements that should share mechanics with an existing element. For example, "Blue Fire" (fire-themed but blue) uses fire attributes, while having its own visual appearance and custom resonance effect. If resonance_dmg_multiplier is not specified, it defaults to the base element's threshold multiplier, making it easy to create elements that share all mechanics except the resonance effect.