Apply Instant Damage and Healing
Use instant effects with execution actions for one-shot attribute changes.
An instant effect emits application-accepted, runs the caller-owned execution action, then emits executed if the action succeeds.
Use this for one-shot work such as:
- damage
- healing
- immediate resource spend
- immediate shield restoration
let mut executor = EffectActionExecutor::new(&mut apply_damage);
EffectApply::definition(&damage_definition, input)
.run_with_executor(&mut effects, &mut context, &mut executor)?;If the action fails, the executed fact is suppressed and the error is returned
through EffectApplyError::Execution.
The action receives the active execution view and caller-owned context. In a larger runtime, keep attribute policy behind a consumer-owned wrapper and let the effect action call that wrapper:
fn apply_effect_payload(
context: &mut EffectActionContext,
execution: EffectExecutionView<'_, CombatTags, EffectPayload>,
) -> Result<(), CombatError> {
let damage = match *execution.payload {
EffectPayload::Damage { amount } => amount,
EffectPayload::Bleed { damage_per_tick } => damage_per_tick,
EffectPayload::AttackSpeedBonus { .. }
| EffectPayload::MaxHealthBonus { .. }
| EffectPayload::Cooldown => return Ok(()),
};
context
.attributes
.apply_damage(execution.target_id, damage);
Ok(())
}Use instant effects when the effect itself is the event boundary. Use direct
attribute commands when no effect lifecycle needs to be observed. For example,
basic regeneration might be a direct AttributeSet, while a combat hit should
usually be an effect so UI, analytics, scripting, and combat logs can all
observe the same lifecycle facts.
Use this with: