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 defense reduced by 30%) | 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) | 14 seconds (280 ticks) |
| ENERGY | Energy resonance explosion, applies Overload effect (damage taken by target increased by 20%) | 14 seconds (280 ticks) |
| NATURAL | Natural resonance explosion, applies Bloom effect (target takes 1 damage per second and receives 20% universal vulnerability) | 12 seconds (240 ticks) |
| QUANTUM | Quantum resonance explosion, applies Break effect (all damage to target ignores defense) | 8 seconds (160 ticks) |
| ETHER | Ether resonance explosion, applies Corruption effect (target's resistance to all damage types reduced by 20% and takes periodic damage) | 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 defense reduced by 10% + 10% per additional negative effect, max 50% reduction) | 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) |
accumulation_multiplier field will not affect it.
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 |
Abloom 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 | #FF19FF |
| Break | abloom:break |
All damage to target ignores defense | #9400D3 |
| Rupture | abloom:rupture |
Targetβs defense is reduced by 30% | #C0C0C0 |
| Bloom | abloom:bloom |
Target takes 1 damage per second and receives 20% universal vulnerability | #32CD32 |
| Overload | abloom:overload |
Damage taken by target increased by 20% | #FF00FF |
| Windswept | abloom:windswept |
Applying other elemental damage triggers resonance explosion | #00FFFF |
| Corruption | abloom:corruption |
Target's resistance to all damage types reduced by 20% and takes periodic damage | #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% | #FF1A5 |
| Eclipse | abloom:eclipse |
Target's defense reduced by 10% + 10% per additional negative effect, max 50% | #4B0082 |
| Critical Gain | abloom:critical_gain |
+30% crit damage, +15% crit chance, +5% attack speed | #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 |
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.
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.
ElementalWeaponComponent (item component)ElementalWeaponRegistry lookupElementType.fromVanillaDamageType() fallback| Enchantment ID | Mapped Element | Type |
|---|---|---|
minecraft:fire_aspect |
FIRE | Vanilla enchantment |
minecraft:flame |
FIRE | Vanilla enchantment (bow) |
Other mods can register their custom enchantments to map to Abloom elements by adding entries to the enchantment-element mapping. Currently, this requires using reflection or waiting for a public API, as the mapping is stored in a private static map in ElementDamageHandler.
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;
import java.lang.reflect.Field;
import java.util.concurrent.ConcurrentHashMap;
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.
* Uses reflection to access Abloom's private ENCHANTMENT_ELEMENT_MAP.
*/
public static void registerEnchantmentMappings() {
try {
Field mapField = ElementDamageHandler.class.getDeclaredField("ENCHANTMENT_ELEMENT_MAP");
mapField.setAccessible(true);
@SuppressWarnings("unchecked")
ConcurrentHashMap<ResourceLocation, com.auranite.abloom.util.ElementType> map =
(ConcurrentHashMap<ResourceLocation, com.auranite.abloom.util.ElementType>) mapField.get(null);
// Map custom enchantments to element types
ResourceLocation iceAspectId = ResourceLocation.fromNamespaceAndPath("mymod", "ice_aspect");
map.put(iceAspectId, com.auranite.abloom.util.ElementType.ICE);
ResourceLocation electricAspectId = ResourceLocation.fromNamespaceAndPath("mymod", "electric_aspect");
map.put(electricAspectId, com.auranite.abloom.util.ElementType.ELECTRIC);
// Example: Map a thunder enchantment to ELECTRIC
ResourceLocation thunderId = ResourceLocation.fromNamespaceAndPath("mymod", "thunder_strike");
map.put(thunderId, com.auranite.abloom.util.ElementType.ELECTRIC);
} catch (NoSuchFieldException | IllegalAccessException e) {
System.err.println("[MyMod] Failed to register enchantment-element mappings: " + e.getMessage());
}
}
}
// 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
}
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)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",
"basic_element": "WATER",
"accumulation_multiplier": 12.0,
"crit_chance": 0.3,
"crit_damage": 0.8
}
Fields for Single-Element Weapons:
item: Item ID (namespace:item_id)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)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)