All Docs Documentation Version: Base (Free) Influence System Ultimate
Simple Attribute Forge Ultimate

Modifier System

Deep dive into the core architecture for creating buffs, debuffs, and attribute modifications.

System Overview

The Modifier System allows you to create temporary or permanent changes to attributes with full conditional logic support. It integrates with the Base tier's three-value architecture:

Three-Value Architecture
totalValue = baseValue + formulaBonus + modifierBonus Where: - baseValue = Equipment, upgrades, permanent stat changes - formulaBonus = Influence System calculations - modifierBonus = Modifier System (buffs, debuffs, status effects)

Modifiers write to modifierBonus, keeping them separate from base stats and formula calculations. This prevents feedback loops and allows clean removal.

Core Classes

SimpleAttributeModifierGroup

The main container class for a modifier. Each group can contain multiple AttributeModifications and defines the modifier's identity, timing, and behavior.

Identity Properties
PropertyTypeDescription
namestringDisplay name for the modifier
descriptionstringHuman-readable description
tagstringCategory tag for grouping (e.g., "buff", "curse", "equipment")
idstringUnique GUID assigned at runtime
Timing Properties
PropertyTypeDescription
durationfloatDuration in seconds. 0 or negative = permanent
priorityintApplication order. Higher = applied later
stackableboolCan multiple instances stack?
maxStacksintMaximum stack count (if stackable)
timeRemainingfloatRuntime: remaining duration
currentStacksintRuntime: current stack count
Behavior Flags
PropertyTypeDescription
isDebuffboolMarks as negative effect (for UI/dispel logic)
isHiddenboolHide from player-facing UI
canBeDispelledboolCan be removed by cleanse/dispel effects
persistsThroughDeathboolSurvives character death/respawn
refreshOnReapplyboolResets duration when reapplied
Requirements System
PropertyTypeDescription
requiredLevelintMinimum character level to apply (0 = no requirement)
categorystringCategory string (offensive, defensive, utility, passive)
incompatibleModifiersList<string>Modifier names that block this one
requiredModifiersList<string>Modifier names required for this one to apply
Events
EventTypeDescription
onApplyUnityEventFired when modifier is applied
onRemoveUnityEventFired when modifier is removed
onExpireUnityEventFired when modifier expires (duration ends)
onTickUnityEvent<float>Fired on each tick for DoT/HoT effects

Key Methods

// Apply modifier to target bool success = group.ApplyTo(ISimpleAttributeDataSource target); // Remove modifier from target bool success = group.RemoveFrom(ISimpleAttributeDataSource target); // Update duration (call in Update loop for timed modifiers) bool expired = group.UpdateTime(float deltaTime); // Check state bool isPermanent = group.IsPermanent(); // duration <= 0 bool isExpired = group.IsExpired(); // duration > 0 && timeRemaining <= 0

AttributeModification

Represents a single attribute change within a modifier group. Each modification targets one attribute with a specific change type and value.

Basic Configuration
PropertyTypeDescription
targetAttributestringAttribute name to modify
typeModifierTypeHow to apply the value (Flat, Percentage, Multiply)
valuefloatThe modification amount

ModifierType Enum

Flat

Add/subtract a fixed value.
+50 Health, -10 Stamina

Percentage

Add/subtract a percentage of base.
+25% Health, -15% Speed

Multiply

Multiply the total value.
x1.5 Damage, x0.5 Defense

Value Targeting
PropertyTypeDescription
modifyBaseValueboolAffects base stat (standard behavior)
modifyCurrentValueboolAffects current value (healing/damage)
modifyMinValueboolAffects minimum boundary
modifyMaxValueboolAffects maximum boundary
Value Targeting: Most modifiers use modifyBaseValue = true. Use modifyCurrentValue for instant damage/healing effects. Use modifyMaxValue to change maximum health/mana caps.
Effect Behavior
PropertyTypeDescription
isPermanentboolSurvives scene changes
applyOverTimeboolApply effect over time (DoT/HoT)
tickIntervalfloatSeconds between ticks for DoT/HoT
removeWhenConditionsMetboolAuto-remove when conditions become false
Conditional Logic
PropertyTypeDescription
enableConditionsboolEnable condition checking
conditionsList<AttributeCondition>Attribute-based conditions
modifierConditionsList<ModifierCondition>Modifier presence conditions

See Conditions System for detailed documentation on AttributeCondition and ModifierCondition.

ARPG Regeneration System

SimpleAttributeModifierGroup includes built-in support for modifying regeneration rates and delays - essential for ARPG status effects.

Regen Modification Properties
PropertyTypeDescription
modifyRegenRateboolEnable regen rate modification
regenRateTypeModifierTypeFlat, Percentage, or Multiply
regenRateValuefloatValue for regen rate modification
modifyRegenDelayboolEnable regen delay modification
regenDelayTypeModifierTypeFlat, Percentage, or Multiply
regenDelayValuefloatValue for regen delay modification
disableRegenerationboolCompletely disable regeneration

Examples

// Poison: Disable health regeneration group.disableRegeneration = true; // Blessing: +50% regen rate group.modifyRegenRate = true; group.regenRateType = ModifierType.Percentage; group.regenRateValue = 50f; // Quick Recovery: -2 seconds regen delay group.modifyRegenDelay = true; group.regenDelayType = ModifierType.Flat; group.regenDelayValue = -2f;

See Regen Modifiers for detailed documentation and stacking behavior.

SimpleModifierTracker

Static utility class for tracking and querying active modifiers across all targets. Essential for ModifierCondition evaluation and modifier management.

Querying Modifiers

// Check if target has a specific modifier bool hasPoison = SimpleModifierTracker.HasModifierByName(attributes, "Poison"); // Check if target has any modifier with tag bool hasCurse = SimpleModifierTracker.HasModifierByTag(attributes, "curse"); // Get all active modifiers List active = SimpleModifierTracker.GetActiveModifiers(attributes); // Get modifiers by name (can have multiple stacks) List poisons = SimpleModifierTracker.GetModifiersByName(attributes, "Poison"); // Get count of active modifiers int count = SimpleModifierTracker.GetActiveModifierCount(attributes);

Removing Modifiers

// Remove all modifiers with name int removed = SimpleModifierTracker.RemoveModifiersByName(attributes, "Poison"); // Remove all modifiers with tag int removed = SimpleModifierTracker.RemoveModifiersByTag(attributes, "curse"); // Remove all modifiers from target SimpleModifierTracker.RemoveAllModifiers(attributes); // Clear entire tracker (use with caution) SimpleModifierTracker.ClearAll();
Note: Modifiers are automatically registered/unregistered when ApplyTo() and RemoveFrom() are called. You don't need to manually register modifiers.

Modifier Lifecycle

1. Creation - Modifier group is instantiated
v
2. Application - ApplyTo() called, registered with tracker
v
3. Active - Modifier effects applied to attributes
v
4. Update - UpdateTime() called for duration tracking
v
5. Expiration/Removal - RemoveFrom() called or duration expires

Managing Timed Modifiers

public class ModifierManager : MonoBehaviour { private List activeModifiers = new List(); void Update() { // Update all timed modifiers for (int i = activeModifiers.Count - 1; i >= 0; i--) { var modifier = activeModifiers[i]; if (!modifier.IsPermanent()) { bool expired = modifier.UpdateTime(Time.deltaTime); if (expired) { modifier.RemoveFrom(target); activeModifiers.RemoveAt(i); } } } } public void AddModifier(SimpleAttributeModifierGroup modifier) { if (modifier.ApplyTo(target)) { activeModifiers.Add(modifier); } } }

Best Practices

Use Tags for Categories

Group related modifiers with tags: "buff", "debuff", "curse", "equipment", "consumable". Makes bulk operations easy.

Set Appropriate Priorities

Use priority to control application order. Equipment (100) -> Buffs (200) -> Debuffs (300) -> Ultimate abilities (400).

Use Requirements for Synergies

requiredModifiers for combo effects, incompatibleModifiers to prevent stacking similar buffs.

Leverage Behavior Flags

isDebuff for dispel targeting, canBeDispelled for cleanseable effects, persistsThroughDeath for permanent curses.