Syntax and Target Modes
The `/damage` command has two distinct syntax branches depending on whether the damage is purely environmental or caused by another entity in the world. Understanding the difference between these two branches is critical because they change how mobs react, how death messages are formatted, and how loot tables evaluate drop conditions.
The first branch applies unattributed damage: `damage <target: target> <amount: int> [cause: DamageCause]`. When you use this form, the target takes the specified amount of damage (measured in half-hearts, where 2 equals one full heart). If you omit the `cause` argument, the game defaults to the `none` cause, which applies raw damage without specific elemental properties. If a player dies to this branch, the death message will reflect a generic environmental death depending on the cause you picked.
The second branch attributes the damage to a source entity: `damage <target: target> <amount: int> <cause: DamageCause> entity <damager: target>`. Notice that `cause` is mandatory in this branch; you cannot omit it if you want to use the `entity` keyword. The `damager` selector must resolve to a single entity—if your selector matches multiple entities (such as `@e[type=zombie]`), the command will fail to execute. Always include `c=1` in your damager selector unless you are using `@s`.
| Parameter | Type | What it does | Notes |
|---|---|---|---|
| target | Selector / Player | The entity or entities that will receive the damage. | Can match multiple entities at once. |
| amount | Integer | The amount of damage to deal in half-hearts. | Must be 0 or greater. 0 triggers knockback and hurt animations without reducing health. |
| cause | DamageCause Enum | The category of damage applied (e.g., fire, magic, entity_attack). | Determines which armor enchantments, potion effects, or immunities apply. |
| entity <damager> | Selector | Credits a specific entity as the attacker. | Must resolve to a single entity. Triggers aggro, Thorns, and player_kill loot conditions. |
Understanding Damage Causes and Mitigation
The `DamageCause` parameter is not just cosmetic flavor for the chat box; it hooks directly into Bedrock's internal combat and resistance formulas. When you deal damage with a specific cause, the target entity runs that damage through its natural immunities, armor ratings, status effects, and enchantments before subtracting the final value from its health pool.
For example, if you run `/damage @e[type=blaze] 10 fire_tick`, nothing will happen because Blazes are natively immune to fire-related causes. Similarly, if a player is wearing boots with Feather Falling IV and you hit them with `/damage @s 12 fall`, the enchantment will absorb a large portion of that damage just as if they had fallen off a cliff. If you want your command to respect standard survival gear—such as custom turrets that deal `projectile` damage so Projectile Protection armor remains useful—you should pick the matching gameplay cause.
On the other hand, mapmakers and add-on creators often need to deal true damage that ignores armor, Resistance potions, and enchantments entirely. For guaranteed health removal, `override` and `suicide` are your most reliable options. They bypass standard mitigation layers and strip health directly, making them ideal for custom health-cost mechanics, out-of-bounds punishment zones, or scripted death sequences.
| DamageCause | Respects Armor | Special Behavior and Immunities |
|---|---|---|
| none | No | Default cause when omitted. Deals direct damage with generic sound and tilt. |
| override | No | Bypasses armor, Resistance, and most damage immunities. Ideal for true damage mechanics. |
| entity_attack | Yes | Standard melee damage. Blocked by shields if directional, reduced by standard armor and Protection. |
| projectile | Yes | Reduced by armor and Projectile Protection. Ignored by Endermen (they will teleport or ignore it). |
| magic | No | Bypasses standard armor durability and defense points, but is reduced by the Protection enchantment and Resistance effect. |
| fire / fire_tick | Yes / No | Negated completely by the Fire Resistance status effect and natural fire immunity on Nether mobs. |
| fall | No | Bypasses armor points, but is reduced by Feather Falling and negated on entities with fall immunity (like cats and chickens). |
| drowning | No | Bypasses armor. Negated by the Water Breathing or Conduit Power effects. |
| void | No | Bypasses armor and survival protections. Deals fatal damage even to heavily buffed targets. |
Attributing Kills, Aggro, and Knockback
Using the `entity <damager>` branch unlocks complex interactions between mobs and players. When Entity A damages Entity B via this command, the game treats it as a real attack. If Entity B is a neutral or hostile mob with a standard target-acquisition AI goal ( specifically `minecraft:behavior.hurt_by_target`), Entity B will immediately turn hostile toward Entity A and begin pathfinding to attack it. You can use this to force two custom mobs to fight each other by dealing `0` damage between them.
Dealing `0` damage with `entity_attack` is a well-known recipe for triggering combat side effects without altering health pools. When an entity takes `0` damage from a damager, it still flashes red, plays its hurt sound, triggers the `minecraft:on_hurt` trigger, and receives directional knockback away from the damager's current position. If the target is wearing armor with the Thorns enchantment, the damager will even take Thorns recoil damage.
Kill attribution also matters for loot tables and experience orbs. Many vanilla and custom loot tables use the `killed_by_player` condition to gate rare drops (like Blaze Rods or spider eyes) so they cannot be farmed automatically with fall traps. If your add-on introduces a custom magic wand or a summonable minion that kills mobs via function files, you must route the `/damage` command's `damager` parameter back to the player (`@p` or a tagged owner). When the mob dies to player-attributed command damage, it drops experience orbs and rolls its loot table as if the player struck it with a sword.
# Run as the casting player (@s) at their current location
# Visual and audio feedback for the spell
particle minecraft:dragon_breath_trail ~~~
playsound mob.evoker.cast_spell @a ~~~ 1.0 1.2
# Deal 14 magic damage to all nearby monsters within 6 blocks, excluding the caster
# Credits @s (the caster) so XP drops and killed_by_player loot conditions succeed
damage @e[rm=0.1,r=6,family=monster] 14 magic entity @s
# Apply a secondary 0-damage hit to knocked back nearby animals without hurting them
damage @e[rm=0.1,r=4,family=mob,type=!player] 0 entity_attack entity @sTriggering Custom Behavior via Damage Sensors
One of the strongest patterns in Bedrock add-on development is pairing the `/damage` command with the `minecraft:damage_sensor` entity component. While `/event` is usually preferred for simple state changes, `/damage` lets you pass both a specific `cause` and an `other` entity reference into an entity's JSON evaluation context at the exact same time.
In the example below, a custom arcane crystal entity is configured to ignore all normal attacks (`deals_damage: false` or `no` depending on format version; in modern versions, string values `"no"`, `"yes"`, and `"no_but_side_effects_apply"` are used alongside boolean support in older formats, though boolean `false` remains widely used in 1.20.x). However, when hit specifically with `magic` damage from a player or a command recipe, it fires an entity event that shatters the crystal and buffs the attacker.
Because the `/damage` command passes the `damager` entity into the sensor, the filter `"subject": "other"` inside the `damage_sensor` block will evaluate against whichever entity you placed after the `entity` keyword in your command. This gives you a clean bridge to establish two-way communication between two separate entities without needing scoreboard ID systems.
{
"format_version": "1.20.40",
"minecraft:entity": {
"description": {
"identifier": "wiki:arcane_crystal",
"is_spawnable": true,
"is_summonable": true
},
"components": {
"minecraft:health": {
"value": 20,
"max": 20
},
"minecraft:damage_sensor": {
"triggers": [
{
"on_damage": {
"filters": {
"all_of": [
{
"test": "has_damage",
"value": "magic"
},
{
"test": "is_family",
"subject": "other",
"value": "player"
}
]
},
"event": "wiki:crystal_activated"
},
"deals_damage": false
},
{
"on_damage": {
"filters": {
"test": "has_damage",
"operator": "not",
"value": "override"
}
},
"deals_damage": false
}
]
}
},
"events": {
"wiki:crystal_activated": {
"queue_command": {
"command": [
"effect @p[r=8] regeneration 10 1 true",
"particle minecraft:totem_particle ~~~",
"kill @s"
]
}
}
}
}
}Handling Invulnerability Frames (Hurt Cooldown)
When you start chaining `/damage` commands in repeating command blocks or tick functions, you will quickly run into Minecraft's built-in invulnerability frames (often called i-frames or hurt time). Whenever an entity takes damage, it enters a 10-tick (0.5 second) cooldown period. During these 10 ticks, if you run another `/damage` command for the same or a lower amount of damage, the game completely ignores it.
If you deal a higher amount of damage during the 10-tick window than the initial hit, the game only applies the difference between the two values. For example, if you run `damage @p 4 magic` on tick 1, and `damage @p 6 magic` on tick 2, the player takes 4 damage on tick 1 and only 2 additional damage on tick 2 (for a total of 6, not 10). Consequently, running `damage @a 1 fire` inside a 20-ticks-per-second function will only hurt the player twice a second, not twenty times.
If you are building a rapid-fire weapon or a beam attack in a behavior pack and need every single tick or projectile to register full damage, you cannot bypass this cooldown using the `/damage` command alone. In JSON, only certain causes like `void` or `override` occasionally bypass specific immunity checks, but standard hurt timers still throttle rapid identical hits. To build true multi-hit attacks in a single tick, you must either accumulate the damage into a single larger `/damage` call per half-second, or switch to the `@minecraft/server` Script API where `Entity.applyDamage()` allows more granular control in modern betas and releases.
Environmental Hazard Recipe: Toxic Swamp Zones
A common use case for `/damage` in adventure maps and survival overhaul add-ons is creating localized environmental hazards based on block detection. Instead of applying the Poison effect—which cannot reduce a player below 1 health (half a heart) and clutters the screen with status particles—you can use `execute if block` combined with `/damage` on a scoreboard timer to create lethal terrain.
In this recipe, a tick function increments a timer scoreboard for all players standing in water inside a specific biome or standing on mud blocks. Every 40 ticks (2 seconds), the function deals 2 `drowning` or `magic` damage and resets their timer. This pacing avoids invulnerability frame collisions, feels readable to the player, and produces a sensible death message if their health reaches zero.
# Add 1 to the hazard timer for players standing directly on mud
execute as @a at @s if block ~~-0.1~ minecraft:mud run scoreboard players add @s wiki_mud_timer 1
# Reset the timer if the player steps off the mud
execute as @a at @s unless block ~~-0.1~ minecraft:mud run scoreboard players set @s wiki_mud_timer 0
# At 40 ticks (2 seconds), apply 2 magic damage, play a sizzle sound, and loop the timer
execute as @a[scores={wiki_mud_timer=40..}] at @s run damage @s 2 magic
execute as @a[scores={wiki_mud_timer=40..}] at @s run playsound random.fizz @s ~~~ 0.5 0.8
execute as @a[scores={wiki_mud_timer=40..}] run scoreboard players set @s wiki_mud_timer 0Which versions this applies to
Introduced in Minecraft Bedrock 1.18.10 as part of the standard vanilla command set. No experimental toggles are required to use `/damage` in command blocks, `.mcfunction` files, or entity event `queue_command` blocks. Make sure your `manifest.json` `min_engine_version` is set to at least `[1, 18, 10]` so functions using this command parse and load cleanly.
When it does not work
| What you see | Why | The fix |
|---|---|---|
| Command fails with: "Selector must be player-type or single entity" or "Too many targets matched selector" | You used a multi-target selector like `@e[type=skeleton]` for the `<damager>` argument after the `entity` keyword. Bedrock requires the source of the damage to be a single, unambiguous entity. | Append `c=1` to your damager selector (for example, `damage @p 5 entity_attack entity @e[type=skeleton,c=1]`) or execute the command as the damager and use `@s` (`execute as @e[type=skeleton] at @s run damage @p[r=3] 5 entity_attack entity @s`). |
| Function fails to load on world startup with a syntax error on the `/damage` line | You either used the `entity <damager>` branch without specifying a `DamageCause` first (e.g., `damage @p 5 entity @s`), or your `manifest.json` `min_engine_version` is set below `1.18.10`. | Always include a valid cause before the `entity` keyword (such as `damage @p 5 entity_attack entity @s`), and update `min_engine_version` in your behavior pack's `manifest.json` to `[1, 19, 0]` or newer. |
| The command outputs "Applied damage to..." in chat, but the target takes 0 health loss | The target is either in Creative/Spectator mode, currently inside its 10-tick invulnerability window from a previous hit, naturally immune to the `DamageCause` you chose (like using `fire` on a Nether mob or `fall` on a chicken), or has a `minecraft:damage_sensor` component intercepting that cause with `"deals_damage": false`. | Test against a player in Survival mode, space your commands at least 10 ticks apart, or change the cause to `override` to bypass natural mob immunities and armor. |
| Syntax error: Unexpected "<cause>": at "damage @s 5 >><cause><<" | You used a damage cause identifier from Java Edition (such as `generic`, `outOfWorld`, or `player_attack`) or an identifier from entity death tables that is not part of the command's `DamageCause` enum. | Replace the cause with a valid Bedrock enum value. Use `none` instead of `generic`, `void` instead of `outOfWorld`, and `entity_attack` instead of `player_attack`. |
Reference, straight from the game files
Read out of the game itself, so the ids match the version you are building for.
