Skip to content

Alembic Damage Types

dhyces edited this page Aug 27, 2024 · 3 revisions

Alembic allows you to semi-dynamically create custom damage type wrappers and damage types, along with their associated attributes, using almost entirely datapacks.

For Mod Developers

Inside your mod's resources folder, create a folder called defaultresources. Inside that, a folder called alembic_pack, with a folder with the name of your mod id inside. Inside that, create a folder called attribute_sets. In here you will place your damage type attribute set JSONs. The remaining JSONs go into the data folder as per normal datapack JSONs. See the examples below for full path examples.

For Modpack Developers

Inside the root directory of your modpack, you will find a folder called globalresources after you've ran the game at least once. In this folder, you'll create a folder - which can be named anything. In here, you will need alembic_pack, then inside that, your pack id, then inside that again, attribute_sets. Here is where you will create your damage type attribute set JSONs. The remaining JSONs go into a datapack. See the examples below for full path examples.

Particle Registry

For every simple particle you want to register via Alembic for a Particle tag, you must put the id inside particles.json inside the alembic folder, the same place that the attribute_sets folder is.

Attribute Sets

Attribute sets are a collection of attributes that are related to your damage type. The json file name has to be the same as your damage type for it to correctly find it.

Example

{
  "damage_attribute": {
    "base": 0,
    "min": 0,
    "max": 1024
  },
  "resistance_attribute": {
    "base": 0,
    "min": -1024,
    "max": 1024
  },
  "resistance_potion": {
    "value": 0.1,
    "operation": "MULTIPLY_BASE",
    "base_duration": 600,
    "amplification_per_level": 1,
    "max_amplifier": 2,
    "max_level": 2,
    "color": "#51b200",
    "recipe": {
      "reagent": "minecraft:slime_ball",
      "base": {
        "type": "forge:nbt",
        "item": "minecraft:potion",
        "count": 1,
        "nbt": {
          "Potion": "minecraft:awkward"
        }
      }
    }
  }
}

damage_attribute is the attribute associated with dealing damage.
resistance_attribute is the attribute used to reduce damage taken for this damage type.
resistance_potion is a potion that can be brewed to give a resistance effect, like how vanilla's damage resistance effect.

  • value is the amount to reduce damage by. So with the MULTIPLY_BASE operation, 0.1 * 100% = 10% reduction.
  • operation is the type of operation to perform when applying the potion effect. The options are MULTIPLY_BASE, MULTIPLY_TOTAL, and ADDITION.
  • base_duration is the initial duration for the first level of the potion. If max_level is greater than 1, then there will be n-1 potions created with a duration of base_duration * level.
  • amplification_per_level is the amount to increase the amplifier by for every level of the potion, up to the max amplifier.
  • max_amplifier is the maximum value that the amplifier can be.
  • max_level is the number of potions to create with increasing duration and/or amplifier.
  • color is the color of the potion in the bottle.
  • recipe is a recipe for the potion
    • reagent is the item to put in the top slot of the brewing stand to start brewing the resistance potion. This field is an ingredient type, so it can be any valid ingredient or item.
    • base is the item to put in the bottom 3 slots. This is also an ingredient, so any custom ingredients can be used. As shown above, it's a little convoluted to create an ingredient for an awkward potion, though ingredients make many different recipes possible.

Datapack Structure

Example JSONs:
/defaultresources/alembic_pack/alembic/attribute_sets/true_damage.json

{
  "priority": 1,
  "enchant_reduction": false,
  "enchant_source": "mob",
  "color": "#FFFFFF",
  "tags": [
    {
      "tag_type": "alembic:particle_tag",
      "particle_options": {
        "type": "alembic:true_damage"
      },
      "conditions": "alembic:damage_from_player",
      "scale_with_damage": true
    },
    {
      "tag_type": "alembic:particle_tag",
      "particle_options": {
        "type": "alembic:frostbite"
      },
      "conditions": [
        {
          "condition_type": "alembic:damage_source",
          "damage_source": "minecraft:freeze"
        }
      ]
    },
    {
      "tag_type": "alembic:reference_tag",
      "ref": "alembic:particles/wither"
    }
  ]
}

To break this down:
priority dictates loading priority of the JSON. A higher priority JSON will override all JSONs of a lower priority.
color dictates the color used when damage types are displayed anywhere, for example in chat if they are printed by a tag.
enchant_reduction tells Alembic whether or not to reduce this damage type with enchantments, only Protection currently. enchant_source must be mob, more may come in the future.

Tags

Tags are quite complicated. They are basically functions you can assign to damage types which are ran at various times. Here is a breakdown of all tags in base Alembic:

Particle Tag

This tag allows you to spawn a burst of particles when an entity takes damage.

{
  "tag_type": "alembic:particle_tag",
  "particle_options": {
    "type": "alembic:true_damage"
  }
}

particle_options tells Alembic which particle to create and its attributes when created. Most particles just require a type, which is the same as you would use for the /particle command. Some particle types, like dust, also require "color": [r,g,b] for example. Other modded particle types will have their own particle options. View their source or ask their dev for more info on them.
particle_speed alters the speed at which particles created by the filter move.
scale_with_damage will produce more particles with more damage if true.
scalar is used to multiply the number of particles to spawn. Stacks with scale_with_damage.

Sound Event Tag

This tag will play a sound when the target entity is damaged.

{
  "tag_type": "alembic:sound_event_tag",
  "sound_event": "entity.allay.item_given",
  "volume": 1.0,
  "pitch": 1.5
}

sound_event is the sound event that should be played. This can be found either on the Minecraft Wiki or in-game via the /playsound command.
volume is the volume to play the sound at. This is an optional field and defaults to 1.0.
pitch is the pitch to play the sound with. This is an optional field and defaults to 1.0.

Per Level Tag

This tag allows you to give the player an associated attribute whenever they reach a certain level milestone, up to a cap.

{
  "tag_type": "alembic:per_level_tag",
  "bonus_per_level": 1,
  "max": 10,
  "level_difference": 5,
  "modifier_type": "resistance"
}

bonus_per_level is how much of the attribute to give per level of this tag
max is the maximum amount of the attribute this tag can give
level_difference tells Alembic how often to give this bonus, 5 meaning every 5 levels in this example. modifier_type refers to which corresponding attribute to allocate. This can be resistance, shielding or absorption.

Extend Fire Tag

This tag simply extends the duration of fire on the affected entity.

{
  "tag_type": "alembic:extend_fire_tag",
  "multiplier": 0.25,
  "ignored_sources": [
      "minecraft:in_fire",
      "minecraft:on_fire",
      "minecraft:lava",
      "alembic:soul_fire"
  ]
}

multiplier tells Alembic what percentage of the damage should be added to the fire duration. 0.25 meaning 25% of the damage value should be added to the fire duration.
ignored_sources dictates what damage sources to ignore this damage type from when adding fire time, in this example being inFire, in lava, or onFire will not add time to your fire duration, but taking fire damage from other sources will.

Hunger Tag

This tag gives an amount of an attribute based on the players hunger value.

{
  "tag_type": "alembic:hunger_tag",
  "attribute": "resistance",
  "hunger_amount": 8,
  "amount": -1,
  "operation": "ADDITION"
}

attribute is the attribute of this damage type to give based on the hunger value.
hunger_amount is how often to give this attribute. 8 = every 8 hunger points, or every 4 shanks.
amount is how much to give each time this attribute is given.
operation is the Attribute Modifier Operation for this. Valid values are ADDITION, MULTIPLY_TOTAL, MULTIPLY_BASE.

Branch Tag

This tag allows you to effectively run an "if... else..." block. It will test the conditions of the first part, in the run field, and if it fails it will then run the tag in the else field. Alembic uses this system to determine the particles that should appear for different damage cases.

Example:

(This is expanded from the alchemical_damage type)

{
  "tag_type": "alembic:branch_tag",
  "run": {
    "tag_type": "alembic:particle_tag",
    "particle_speed": 0.35,
    "scalar": 3,
    "particle_options": {
      "type": "alembic:redstone_spark"
    },
    "conditions": [
      {
        "condition_type": "alembic:damage_source",
        "direct_entity": {
          "held_item": "minecraft:redstone_torch"
        }
      }
    ]
  },
  "else": {
    "tag_type": "alembic:particle_tag",
    "particle_speed": 0.35,
    "scalar": 3,
    "particle_options": {
      "type": "alembic:alchemical_reaction"
    }
  }
}

Reference Tag

The reference tag makes it simpler to store large blocks of tags in a single file for use in multiple damage types.

Example:

{
  "tag_type": "alembic:reference_tag",
  "ref": "alembic:particles/wither"
}

The above example will load alembic/alembic/damage_types/tags/wither and use the Alembic tag found in that file. The contents would like something like this:

{
  "tag_type": "alembic:particle_tag",
  "particle_speed": 0.2,
  "scalar": 3,
  "particle_options": {
    "type": "alembic:wither_decay"
  },
  "conditions": [
    {
      "condition_type": "alembic:any",
      "conditions": [
        {
          "condition_type": "alembic:damage_source",
          "direct_entity": "minecraft:wither_skeleton"
        },
        {
          "condition_type": "alembic:damage_source",
          "damage_source": "minecraft:wither_skull"
        },
        {
          "condition_type": "alembic:damage_source",
          "damage_source": "minecraft:wither"
        }
      ]
    }
  ]
}

Conditions

Conditions are a way to apply filters to tags. By default, the following conditions are present:

alembic:damage_source

You may filter by the direct or indirect entity, and/or by the damage_source id, when this condition is ran. The direct entity is the target, and the indirect entity is the attacker.

This layout shows each part of the damage source condition:

  • direct_entity: This can be the ID of an entity (like minecraft:skeleton), an entity tag (like #minecraft:zombies), or an expanded element. This is an optional element. The expanded element would look like the following:
    • entity_type: The ID of an entity (like minecraft:skeleton) or an entity tag (like #minecraft:zombies). This is an optional element.
    • held_item: The ID of an item (like minecraft:iron_sword) or an item tag (like #minecraft:axes). This is an optional element.
  • indirect_entity: This is the same as the above, but is run for the "indirect" entity, like a skeleton that shot an arrow. The arrow is the direct entity and the skeleton is indirect. This is an optional element.
  • damage_source: Either the ID for a vanilla damage type (like minecraft:arrow) or a damage type tag (like #minecraft:is_fire). This is an optional element.

Example:

{
  "condition_type": "alembic:damage_source",
  "direct_entity": {
    "held_item": "minecraft:redstone_torch"
  }
}

alembic:not

If the context for the condition is NOT what is specified in the condition predicate, the tag will run.

Example:

{
  "condition_type": "alembic:not",
  "condition": {
    "condition_type": "alembic:damage_source",
    ""
  }
}

alembic:all

All predicates in the array must be met for the tag to run.

Example:

{
  "condition_type": "alembic:all",
  "conditions": [
    {
      "condition_type": "alembic:damage_source",
      "direct_entity": "minecraft:wither_skeleton"
    },
    {
      "condition_type": "alembic:damage_source",
      "damage_source": "minecraft:wither_skull"
    },
    {
      "condition_type": "alembic:damage_source",
      "damage_source": "minecraft:wither"
    }
  ]
}

alembic:any

If any of the predicates in the list are met, the tag will run

Example:

{
  "condition_type": "alembic:any",
  "conditions": [
    {
      "condition_type": "alembic:damage_source",
      "direct_entity": "minecraft:wither_skeleton"
    },
    {
      "condition_type": "alembic:damage_source",
      "damage_source": "minecraft:wither_skull"
    },
    {
      "condition_type": "alembic:damage_source",
      "damage_source": "minecraft:wither"
    }
  ]
}

alembic:reference

This will take a resource location reference to a file in an enabled datapack.

Example:

{
  "condition_type": "alembic:reference",
  "ref": "my_pack:damage_from_wither"
}

This example will load the conditions specified in the my_pack/alembic/damage_types/conditions/damage_from_wither file, which could look like this:

{
  "condition_type": "alembic:any",
  "conditions": [
    {
      "condition_type": "alembic:damage_source",
      "direct_entity": "minecraft:wither_skeleton"
    },
    {
      "condition_type": "alembic:damage_source",
      "damage_source": "minecraft:wither_skull"
    },
    {
      "condition_type": "alembic:damage_source",
      "damage_source": "minecraft:wither"
    }
  ]
}

Now you can see why it may be advantageous to specify some specific conditions in a separate file to reference in many other places.

Default Features

Alembic offers some bonus features and wrapping for 2 damage type ids: physical_damage and fire_damage. It will handle certain fire related things and attack damage related things differently if these are present.