User Tools

Site Tools


tutorial:damagetypes

Adding a Damage Type (1.19.4+)

Introduction

Sometimes you may want to add a custom damage type to your mod, for example if you're adding a custom damaging fluid similar to lava or a block like a magma block. Since 1.19.4, the creation of new damage types has become data-driven, meaning they are created using JSON files. To use your custom damage type in code however, you're going to need to get its RegistryKey and create a new DamageSource using it. In this tutorial, the “tutorial” namespace is used as a placeholder. If you have a separate modid, feel free to use it instead.

Creating a Damage Type

First, create a json file for your custom damage type following the format here. It should be placed in your mod's data folder in a new subfolder called damage_type. For example:

data/tutorial/damage_type/custom_damage_type.json
  1. {
  2. "exhaustion": 0.1,
  3. "message_id": "custom",
  4. "scaling": "when_caused_by_living_non_player"
  5. }

Our new custom damage type will now cause 0.1 hunger exhaustion each time a player takes damage of this type, and the if the damage is caused by a living, non-player source (like being hit by a Zombie), the amount of damage dealt will scale with the world's difficulty. You can see all possible keys and values on the respective Minecraft wiki page.

Getting our damage type in code

To actually use our new damage type in code, we need to get its RegistryKey and use a method to get the corresponding DamageSource object. Let's create a new class to keep track of our custom damage types and store our helper method.

ModDamageTypes.java
  1. public class ModDamageTypes {
  2.  
  3. /*
  4.   * Store the RegistryKey of our DamageType into a new constant called CUSTOM_DAMAGE_TYPE
  5.   * The Identifier in use here points to our JSON file we created earlier.
  6.   */
  7. public static final RegistryKey<DamageType> CUSTOM_DAMAGE_TYPE = RegistryKey.of(RegistryKeys.DAMAGE_TYPE, new Identifier("tutorial", "custom_damage_type"));
  8.  
  9. public static DamageSource of(World world, RegistryKey<DamageType> key) {
  10. return new DamageSource(world.getRegistryManager().get(RegistryKeys.DAMAGE_TYPE).entryOf(key));
  11. }
  12. }

Our static method of allows us to get the DamageSource we need to actually use our custom damage type in code, as any methods that deal damage will typically take a DamageSource and not a DamageType.

Using our damage type

Now let's use our custom damage type. In this example, lets pretend we have a custom Block that implements the onSteppedOn method, similar to the Magma Block. If you haven't created a Block yet, check out the blocks tutorial.

ExampleBlock.java
  1. public class ExampleBlock extends Block {
  2.  
  3. public ExampleBlock (Settings settings) {
  4. super(settings);
  5. }
  6.  
  7. public void onSteppedOn(World world, BlockPos pos, BlockState state, Entity entity) {
  8. if(entity instanceof LivingEntity) {
  9. entity.damage(ModDamageTypes.of(world, ModDamageTypes.CUSTOM_DAMAGE_TYPE), 1.0f);
  10. }
  11. }
  12. }
You'll notice that Entity#damage takes a DamageSource and not a DamageType as its first argument. This is why we use our helper method of, to get a useable DamageSource of our custom damage type!

Now whenever a ``LivingEntity`` steps on our custom block, they'll take 1 damage (half a heart) using our custom damage type! However, if you notice, when you die from our custom damage type, the death message will simply be “death.attack.custom”! That's no good. We need to provide a translation for when something dies of our custom damage type! Add an entry to your language file:

en_us.lang
{
    [...]
    "death.attack.custom": "%1$s died from a custom damage type!"
    [...]

If you did everything correctly, when you die of our custom damage type, you'll see a proper death message with your username!

Damage type tags

Some types of damage in Minecraft bypass armor, like the Wither potion effect, or drowning damage. If you want to make your custom damage type have effects like bypassing armor or not damaging witches, there are tags for this! You can find a list of Minecraft's damage type tags in data/minecraft/tags/damage_type. To add your custom damage type to one of these tags, create a new json file with the same name in your data/<namespace>/tags/damage_type folder. Note that this file should go in the minecraft namespace, NOT your mod's namespace! Now simply ensure your tag file does not replace the existing tag by adding the replace key, and add your custom damage type into it:

data/minecraft/tags/damage_type/bypasses_armor.json
  1. {
  2. "replace": false,
  3. "values": [
  4. "examplemod:custom_damage_type"
  5. ]
  6. }

A list of the tags and their effects is as follows:

Tag Name Effect Notes
always_hurts_ender_dragons Always deals damage to dragons, no matter where they're hit or during what phase (excludes dying)
always_most_significant_fall Counts a fall as always being the highest height when compared to other falls. Unsure if this actually has a tangible in-game effect.1)
always_triggers_silverfish Always causes Silverfish to call for help from other Silverfish hiding in blocks
avoids_guardian_thorns Does not trigger the Thorns effect when attacking Guardians
burns_armor_stands Deals a flat 4.0 damage to armor stands
bypasses_armor Ignores all armor base protection value. Does not ignore Protection enchantments.
bypasses_effects Bypasses both Resistance effect and Protection enchantments, but not armor.
bypasses_enchantments Ignores all types of Protection enchantments, but not base armor protection.
bypasses_invulnerability Damages players who are invulnerable, such as in Creative or Spectator mode
bypasses_resistance Bypasses Resistance effect
bypasses_shield Bypasses shield blocking Damage types in this tag do not disable shields similar to how Axes do.
damages_helmet Damages the helmet worn by the amount of the damage, and reduces entity's damage taken by 25%.
ignites_armor_stands Sets armor stands on fire or deals 0.15 extra damage if already on fire
is_drowning The player will be invulnerable to damage types in this tag if gamerule drowningDamage is false
is_explosion Affected by Blast Protection enchant. Does not destroy dropped Nether Stars. Does not explode End Crystals. Applies explosive knockback. Triggers TNT minecarts. Destroys frames and drops the item held in them at the same time.
is_fall The player will be invulnerable to damage types in this tag if gamerule fallDamage is false. Fall damage immune entities will ignore damage types in this tag. Affected by Feather Falling enchant.
is_fire Affected by Fire Protection enchant. Does not destroy fireproof items (such as Netherite). Triggers TNT minecarts. Fire immune entities will ignore damage types in this tag. Causes Witches to drink Fire Resistance potions.
is_freezing Deals 5x damage to entities in freeze_hurts_extra_types entity tag (Strider, Blaze, Magma Cube). The player will be invulnerable to damage types in this tag if gamerule freezeDamage is false.
is_lightning Causes Turtles to drop Bowls when killed by a damage type in this tag.
is_projectile Affected by Projectile Protection enchant. Causes Endermen to teleport when damaged by a damage type in this tag.
no_anger Does not anger wolves, zombified piglins, or endermen to their attacker if the damage type used is in this tag.
no_impact Does not trigger entity velocity updates.
witch_resistant_to Witches will take 85% less damage from damage types in this tag.
wither_immune_to The Wither is invulnerable to damage types in this tag.
1)
Has something to do with determining death message when falling out of the bottom of the world. Have yet to see the effect in testing
tutorial/damagetypes.txt · Last modified: 2023/09/24 18:53 by mattidragon