The damage effect tag determines the results of damage application in a wide range of use cases, including but not limited to: projectile impacts, detonations, melee attacks, falling, and vehicle collisions. They can be part of an effect.
A damage effect is not strictly about applying shield and health damage to units; these tags can have an area of effect, impart acceleration on additional objects like items and projectiles too, and cause screen effects like colour flashes and shaking.
Bleedthrough
When damage to shields exceeds the currently shield vitality, damage carries over to health. When this occurs, the damage multiplier of the shields still carries over to the health damage. This even occurs if the current shield vitality is 0. The result is that the initial carryover health damage may be higher than expected with weapons like the plasma rifle, which have a 2x shield multiplier. Subsequent shots will impact the body and use its material type modifiers instead.
Impact damage formula
When applying a damage_effect
as a projectile impact, the game may take projectile fields into account as well. When air or water damage ranges are set, the projectile's travel distance will scale damage between damage lower bound and a random selection between upper bounds. If air damage range is not set, it always uses the random high bound.
Firstly, the game randomly picks a value between the two upper bounds (will always be the same if both values are the same). Up to the projectile minimum air damage range, 100% unmodified damage is applied. However, past the minimum and up to the maximum damage ranges, damage linearly scales to the lower bound. Past this distance, the projectile disappears (but does not detonate).
In pseudocode, and assuming within max range:
//falloff is 0 to 1 based on travel distance between air damage ranges
let falloff = max(0,
(travel_distance - air_damage_min) /
(air_damage_max - air_damage_min)
);
//given a random_value between 0 and 1, interpolate between the two high bounds
let upper_bound_delta = upper_bound_2 - upper_bound_1;
let random_upper_bound = upper_bound_1 + random_value * upper_bound_delta;
//interpolate between lower and random upper bound
let raw_damage = (
falloff * lower_bound +
(1.0 - falloff) * random_upper_bound
);
//finally, damage is scaled by the multiplier for the impacted material
let damage_done = material_damage_multiplier * raw_damage;
Or, more visually:
Related HaloScript
The following are related functions that you can use in your scenario scripts and/or debug globals that you can enter into the developer console for troubleshooting.
Function/global | Type | |
---|---|---|
When an encounter is selected, damage modifiers are logged at the bottom of the screen. | Global | |
Any damage_ | Global | |
When enabled, looking at any collideable object and pressing Space will display the object's body and shield vitalities on the HUD. | Global | |
Logs damage to the player as messages at the bottom of the screen. Includes body and shield vitality and the damage source. | Global | |
Toggles the display of screen flashes, such as those from a damage_ | Global |
Structure and fields
Field | Type | Comments | ||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
radius | Bounds | The minimum radius determines the sphere in which damage is 100% of damage upper bound. Damage fades linearly to damage lower bound at the maximum radius. Outside the maximum radius, 0 damage is dealt. The aoe core radius field does not affect this calculation. | ||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||
cutoff scale | float | |||||||||||||||||||||||||||||||||||||||||||
flags | bitfield | |||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||
type | enum | |||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||
priority | enum | |||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||
duration | float | |||||||||||||||||||||||||||||||||||||||||||
fade function | enum | |||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||
maximum intensity | float | |||||||||||||||||||||||||||||||||||||||||||
color | ColorARGB | |||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||
low frequency vibrate frequency | float | |||||||||||||||||||||||||||||||||||||||||||
low frequency vibrate duration | float | |||||||||||||||||||||||||||||||||||||||||||
low frequency vibrate fade function | enum ? | |||||||||||||||||||||||||||||||||||||||||||
high frequency vibrate frequency | float | |||||||||||||||||||||||||||||||||||||||||||
high frequency vibrate duration | float | |||||||||||||||||||||||||||||||||||||||||||
high frequency vibrate fade function | enum ? | |||||||||||||||||||||||||||||||||||||||||||
temporary camera impulse duration | float | |||||||||||||||||||||||||||||||||||||||||||
temporary camera impulse fade function | enum ? | |||||||||||||||||||||||||||||||||||||||||||
temporary camera impulse rotation | float | |||||||||||||||||||||||||||||||||||||||||||
temporary camera impulse pushback | float | |||||||||||||||||||||||||||||||||||||||||||
jitter | Bounds ? | |||||||||||||||||||||||||||||||||||||||||||
permanent camera impulse angle | float | |||||||||||||||||||||||||||||||||||||||||||
camera shaking duration | float | Controls how long camera shaking lasts. In H1CE and H1CE, short camera shakes (0.05) get skipped occasionally at high FPS since this feature is still tied to frame rate. This is fixed and interpolated by Chimera and by H1A natively. | ||||||||||||||||||||||||||||||||||||||||||
camera shaking falloff function | enum ? | |||||||||||||||||||||||||||||||||||||||||||
camera shaking random translation | float | |||||||||||||||||||||||||||||||||||||||||||
camera shaking random rotation | float | |||||||||||||||||||||||||||||||||||||||||||
camera shaking wobble function | enum | |||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||
camera shaking wobble period | float | |||||||||||||||||||||||||||||||||||||||||||
camera shaking wobble weight | float | |||||||||||||||||||||||||||||||||||||||||||
sound | TagDependency : sound | |||||||||||||||||||||||||||||||||||||||||||
breaking effect forward velocity | float | |||||||||||||||||||||||||||||||||||||||||||
breaking effect forward radius | float | |||||||||||||||||||||||||||||||||||||||||||
breaking effect forward exponent | float | |||||||||||||||||||||||||||||||||||||||||||
breaking effect outward velocity | float | |||||||||||||||||||||||||||||||||||||||||||
breaking effect outward radius | float | |||||||||||||||||||||||||||||||||||||||||||
breaking effect outward exponent | float | |||||||||||||||||||||||||||||||||||||||||||
damage side effect | enum | |||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||
damage category | enum | |||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||
damage flags | bitfield | |||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||
damage aoe core radius | float | Objects within this radius will be damaged regardless of obstructions in the BSP. Outside this radius, there must be a line of sight between the effect and target. Contrary to the Guerilla tooltip, this field does not determine if the damage has an area of effect; see radius. | ||||||||||||||||||||||||||||||||||||||||||
damage lower bound | float | Sets the minimum amount of damage done when this effect is applied in a scaled way. For example, projectiles can have min and max damage ranges for air and water. | ||||||||||||||||||||||||||||||||||||||||||
damage upper bound | Bounds ? | Maximum damage will be randomly chosen from this range. | ||||||||||||||||||||||||||||||||||||||||||
damage vehicle passthrough penalty | float | |||||||||||||||||||||||||||||||||||||||||||
damage active camouflage damage | float | |||||||||||||||||||||||||||||||||||||||||||
damage stun | float | |||||||||||||||||||||||||||||||||||||||||||
damage maximum stun | float | |||||||||||||||||||||||||||||||||||||||||||
damage stun time | float | |||||||||||||||||||||||||||||||||||||||||||
damage instantaneous acceleration | float | Controls how much moveable objects are accelerated by this effect. This is scaled by the acceleration scale field of object. | ||||||||||||||||||||||||||||||||||||||||||
dirt | float | |||||||||||||||||||||||||||||||||||||||||||
sand | float | |||||||||||||||||||||||||||||||||||||||||||
stone | float | |||||||||||||||||||||||||||||||||||||||||||
snow | float | |||||||||||||||||||||||||||||||||||||||||||
wood | float | |||||||||||||||||||||||||||||||||||||||||||
metal hollow | float | |||||||||||||||||||||||||||||||||||||||||||
metal thin | float | |||||||||||||||||||||||||||||||||||||||||||
metal thick | float | |||||||||||||||||||||||||||||||||||||||||||
rubber | float | |||||||||||||||||||||||||||||||||||||||||||
glass | float | |||||||||||||||||||||||||||||||||||||||||||
force field | float | |||||||||||||||||||||||||||||||||||||||||||
grunt | float | |||||||||||||||||||||||||||||||||||||||||||
hunter armor | float | |||||||||||||||||||||||||||||||||||||||||||
hunter skin | float | |||||||||||||||||||||||||||||||||||||||||||
elite | float | |||||||||||||||||||||||||||||||||||||||||||
jackal | float | |||||||||||||||||||||||||||||||||||||||||||
jackal energy shield | float | |||||||||||||||||||||||||||||||||||||||||||
engineer skin | float | |||||||||||||||||||||||||||||||||||||||||||
engineer force field | float | |||||||||||||||||||||||||||||||||||||||||||
flood combat form | float | |||||||||||||||||||||||||||||||||||||||||||
flood carrier form | float | |||||||||||||||||||||||||||||||||||||||||||
cyborg armor | float | Also labeled as simply cyborg in Guerilla. Used to modify damage on all body parts of the cyborg (spartan) biped. | ||||||||||||||||||||||||||||||||||||||||||
cyborg energy shield | float | Damage modifier for the "cyborg energy shield" material type. See the shield material type field of the unit's model_ | ||||||||||||||||||||||||||||||||||||||||||
human armor | float | |||||||||||||||||||||||||||||||||||||||||||
human skin | float | |||||||||||||||||||||||||||||||||||||||||||
sentinel | float | |||||||||||||||||||||||||||||||||||||||||||
monitor | float | |||||||||||||||||||||||||||||||||||||||||||
plastic | float | |||||||||||||||||||||||||||||||||||||||||||
water | float | |||||||||||||||||||||||||||||||||||||||||||
leaves | float | |||||||||||||||||||||||||||||||||||||||||||
elite energy shield | float | Damage modifier for the "elite energy shield" material type. See the shield material type field of the unit's model_ | ||||||||||||||||||||||||||||||||||||||||||
ice | float | |||||||||||||||||||||||||||||||||||||||||||
hunter shield | float |
Acknowledgements
Thanks to the following individuals for their research or contributions to this topic:
- Conscars (Checking multiplayer headshot flag and radii behaviour)
- gbMichelle (Reverse engineering the damage formula)
- Kavawuvi (Invader tag definitions)
- King Feraligatr (Testing EMP effect on shields)
- Mortis (Explaining headshot damage and bleedthrough)
- MosesOfEgypt (Tag structure research)