Ability Modifiers

Modifiers are runtime changes to abilities. Each time an ability is cast, modifiers are evaluated and applied if applicable to the given ability.
Modifiers can either be general (applies to all abilities cast by the invoker) or tied to a specific ability. They can be limited by number of casts or by a given lifetime.
Common examples of what could be considered a modifier is:
- Buffs
- Weapon attachments
- Dynamic attack (Rougelite)
- and more...
General settings
Priority
Since modifiers can manipulate values they need a priority to know in which order they should be applied. A priority 1 modifier is applied befire a priority 5 modifier.
Stops evaluation
If checked, this modifier will stop all lower priority modifiers to be applied for the current cast cycle
Limit to specific abilities
If the modifier should only apply to specific abilities, add them here.
Usages consumption
Determines many times a modifier can be applied before being considered expired.
Unlimited
Will be applied until removed
Per cast with target
Will consume one usage when the ability had a target
Per cast always
Will consume one usage on each cast, regardless of if the ability had a target or not.
Per modification
Will consume one usage every time it modifies a value.
Example: If an ability has two damage effects and a damage modifier with just one usage left, the modifier would only be applied to the first damage effect.
Lifetime
How long the modifier should last before expiring.
If set to 0 it will last until its manually removed or consumed by usages.
If time-handling is set to Manual, you need to call Invoker.TickModifierLifetimes() to expire the modifiers.
Supplied modifiers
The framework comes with the following modifiers out of the box:
Property Modifier

Modifies one (or multiple) properties of an ability.
Property Modifier Stack
A modifiers that is a stack of other property modifiers. All modifiers contained in the stack will be added and removed together when the stack is used as input to Add-/Remove modifier.
Add Effect Modifier
Adds a given effect to abilities when they're cast.
Cancel Effect Modifier
Modifies a given effect to not be applied until this modifier is removed.
Effect Value Modifier
Modifies the value of an Effect. Note that the effect must be derived from ModifiableAbilityEffectSO to be able to be modifiable. There are a few effects supplied that can be modified which you can use as example.
Set AOE Modifier
Adds, changes, or removes the AOE of an ability. This works for all ability types.
Handling modifiers at runtime
Modifiers are added and removed either to an Ability invoker by code, or with Effects. When the modifier is consumed it's automatically removed.
You can see the currently active modifiers on both the AbilityInvoker component and the Ability component in the inspector when in Play-mode
Add modifier with effect
There are few effects supplies with the framework. These can add one or multiple modifiers to the target when an ability hits.
Add modifiers by code
Modifiers are added to invokers by passing a modifier (AbilityModifierBaseSO) to Invoker.AddModifier().
Remove modifiers with effect
Use the RemoveModifierEffect supplied with SPAM.
Remove modifiers with code
Pass a modifier (AbilityModifierBaseSO) to Invoker.RemoveModifier.
Creating new modifiers
See also the included sample "Custom Modifier"
Just as with Effects, you can create your own modifiers that fits your project. This is an advanced feature since the modifiers supplied should cover most use cases, but it can be used to have the features of modifiers interact with your other systems in your project.
To create a new modifier you create your own instance of the modifier base class AbilityModifierBaseSO, for example MyCustomModifierSO : AbilityModifierBaseSO.
This will register the modifier with SPAM, and you can now use the Modifier window to create a new Modifier in your project.
To later retrieve the modifier, you can either loop through Invoker.Modifiers.GenericModifiers and do a type-check in it's modifier type, or listen to the modifier events raised by an AbilityInvoker.
public class ModifierInteraction // MonoBehaviour, custom code..
{
public void UseModifiers()
{
// Obtain a reference to the invoker
var invoker = GetAbilityInvoker();
// Subscribe to it's events
invoker.ModifierAdded += InvokerOnModifierAdded;
invoker.ModifierRemoved += InvokerOnModifierRemoved;
// Or: loop and find your modifier
foreach (var mod in invoker.Modifiers.GenericModifiers)
{
if (mod.Modifier is MyCustomModifierSO customModifier)
{
// Now you can call your own modifier's methods
// or Access it's data
customModifier.MyMethod()
var data = customModifier.MyData;
}
}
}
private void InvokerOnModifierAdded(AbilityModifierBaseSO modifier)
{
if(modifier is MyCustomModifierSO customModifier)
// Now you can access the modifier
}
private void InvokerOnModifierRemoved(AbilityModifierBaseSO modifier)
{
if(modifier is MyCustomModifierSO customModifier)
// Now you can access the modifier
}
}
SPAM Framework Documentation