CombatDamage and Defense
Last modified: 09 October 2024Ninja Combat provides a very flexible damage and defense system, which covers a lot of scenarios, but can also be modified or extended to adjust to your requirements.
Damage Calculation
The Damage applied from an attack is defined by Gameplay Attributes related to damage - BaseDamage
, CriticalHitChance
and CriticalHitMultiplier
.
var crit_roll = random(0, 1)
if critical_hit_chance > crit_roll
then:
return base_damage
else:
return base_damage * critical_damage_multiplier
This logic is present in the UCombatExecution_Damage
Calculation Class, present in the damage-related Gameplay Effects. The values used by this calculation can be fine-tuned in the following ways:
Set By Caller Magnitudes: You can override the base damage or critical hit chance/multiplier by setting their magnitudes using the appropriate data tags.
Damage Multiplier Magnitude: You can add a Damage Multiplier to the calculation, which will be applied to the base damage.
Global Modifier: Damage can be cancelled by the Game Mode or Game State.
Once the damage is defined, is added to the target's PendingDamage
.
Defense Calculation
Incoming damage can be defended in many ways, which can be adjusted (or even removed) via Gameplay Attributes.
Block: Usually from shields. Involves block chance, reduction percent, reduction limit, angle and a stamina cost.
Defense: Any other extra defense layer. Has a defense chance, reduction percent, reduction limit and a stamina cost.
Armor: Flat damage reduction provided by equipped gear.
Invulnerability: Provides full damage cancellation. Usually granted by an ability (buff, evades, etc.)
Last Stand: Reverts fatal damage, granting a certain health percent back and consuming charges.
Global Modifier: Damage can be cancelled by the Game Mode or Game State.
These defense mechanisms are applied in the following order:
if invulnerable
then:
incoming_damage = 0
mitigation_const = 0
if block_chance_test and block_stamina_test and block_angle_test
then:
incoming_damage -= Min(incoming_damage * block_reduction, block_cap)
mitigation_cost += block_cost * incoming_damage
if defense_chance_test and defense_stamina_test
then:
incoming_damage -= Min(incoming_damage * defense_reduction, defense_cap)
mitigation_cost += block_cost * incoming_damage
incoming_damage -= armor_mitigation
if is_fatal_damage then:
apply_last_stand
Here are some examples of how the mitigation can be configured, by adjusting their related Gameplay Attributes:
If the block or defense chance is
1
(meaning 100%), then the character always blocks or defends damage.If the block angle is
180
, then the character can block damage from the sides. If it is360
, then the character can block damage from behind.If the block or defense costs are
0
, then no stamina is required to block or defend, virtually disabling the stamina mechanic.If the block or defense limits are
0
, then they can mitigate as much damage as possible, virtually disabling the defense cap mechanic.
Global Damage Modifier
The system provides an interface, CombatDamageModifierInterface
that can be implemented by your Game Mode or Game State. If you do that, then every damage being applied can be modified or completely cancelled.
The Global Damage Modifier has two important functions:
ShouldCancelDamage
: Determines if the damage should be cancelled, which means no damage reactions would be triggered.ModifyDamage
: Modifies the final damage value, but even a value of zero will trigger damage reactions.
tip
Ninja Factions Integration
Ninja Combat can be integrated with Ninja Factions to automatically disable Friendly Fire.
Handling Damage
Once received damage is confirmed, a Gameplay Event will activate the Hit Reaction Ability. Unless it's a fatal damage, in which case a Gameplay Event will activate the Death Ability instead.
Damage Data
The Damage Manager Component (the default Combat Manager, or a component override) requires a Data Asset, based on NinjaCombatDamageDataAsset
, to customize certain aspects of the "death flow" and add cosmetics to each hit that has been received.
This data asset is set to the Combat Component's Damage Data. It contains the following properties:
Property | Description |
---|---|
| Lifespan applied when destroying the owner. A value of zero destroys the character immediately. |
| Fallback mechanism to avoid relying on certain animations before the character can be destroyed. |
| Cosmetic aspects played whenever a hit happens, fatal or not. |
Damage Handlers can be used for certain cosmetic aspects and will be executed using Local Gameplay Cues. The system provides the following handlers, and you can create your own from NinjaCombatDamageHandler
.
Handler | Description |
---|---|
Camera Shake | Plays a Camera Shake on the actor receiving damage. |
Combat Interfaces | Invokes the Melee and Ranged Combat Interfaces on the damage source, to play their own cosmetics. |
Dissolve | Dissolves the character, using the |
Physical Animation | Triggers a Physical Animation, using a component implementing |
Damage Gameplay Cues
While working with the Damage Handlers, or any other objects related to damage cosmetics, such as certain methods in the combat interfaces, you can gather information about the damage type from the Gameplay Cue's Aggregated Source Tags.
Any Gameplay Tags from the attacker, weapon and Gameplay Effects are available. The Combat System includes the following types of damage:
Damage Type | Description |
---|---|
| The attack was blocked. |
| The attack broke the blocking state. |
| The attack was a critical hit. |
| The attack applied fatal damage. |
| The attack was strong enough to result in a knockback. |
| The attack was fatal but triggered a last stand. |
| The attack was mitigated by a defense mechanism. |
| The attack was a melee attack. |
| The attack was a ranged attack. |
| The attack result in a stagger. |
note
Multiple Damage Types
The same attack can contain multiple types of damage, such as "Melee" and "Blocked", or "Ranged" and "Fatal". You can filter tags by "Combat.Effect.Damage" to learn everything about the incoming damage, whenever necessary.