Concept: Modifiers and Dynamic Tags
Two runtime mechanisms that change behavior without authoring a new gameplay effect.
Property modifiers
| Kind | Scope | API |
|---|---|---|
| Tag-based | Every ability carrying a tag | AddTagBasedModifier / RemoveTagBasedModifier |
| Ability-specific | One ability spec | AddAbilitySpecificModifier / RemoveAbilitySpecificModifier |
Use these for temporary, code-driven changes - a shrine that halves all fire cooldowns for 30 seconds. For permanent, designer-authored changes prefer an augment.
Dynamic tag rules
AddDynamicTagRule changes block/cancel relationships at runtime, layered on top of the static UCrimsonAbilityTagRelationshipMapping. A status effect that makes a character unable to dodge adds a rule rather than editing the mapping asset.
Gameplay Effect components
| Component | Does |
|---|---|
UCrimsonModifierGameplayEffectComponent | Applies property modifiers as part of an effect. |
UCrimsonAccumulateGameplayEffectComponent | Accumulates a value across applications. |
UCrimsonGameplayEffectComponent_ApplyToInstigator | Applies the effect back to the instigator as well as the target. |
Components attach to a UGameplayEffect asset, so effect-side behavior needs no subclassing.
See also
- How-To: Block and Cancel by Tag
- Concept: Ability System Component
Reading an ability-scoped attribute
GetGameplayAttributeValue on the ASC returns the character-wide value and knows nothing about ability-scoped modifiers. An attribute read that way silently ignores every augment scoped to one ability.The failure is completely silent: the augment validates, the editor summary shows the correct number, and the game behaves exactly as if it were never equipped. If you add an attribute and want augments to scope it per-ability, you must read it through one of the two accessors below.
Which one you use depends on what you are holding - an ability instance, or just a spec handle.
Use Get Ability Scoped Attribute Value (Ability = self, Attribute = your attribute, Default Value = the neutral value for that stat - 1.0 for a multiplier, 0.0 for a bonus). It is a pure node, so you can read it inline wherever you need the number.
Reading the attribute with Get Float Attribute instead is the mistake this page exists to prevent - it returns the character-wide value.
Value += Additive, then Value *= (1 + Multiplicative) - the same order as a GameplayEffect execution. A Multiplicative of 1.0 therefore means +100%, not x1.Prefer these helpers over calling
GetAbilitySpecificModifiers by hand. That convention used to be copy-pasted into each consumer, and the copies drifted.Attributes that cannot be ability-scoped
Some attributes are read where no ability is in scope, and no accessor can change that. Scoping them to a single ability is a category error rather than a missing feature - use a Property mutation or an ordinary gameplay effect instead.
| Shape | Example | Why not |
|---|---|---|
| A character-wide pool | Health, MaxHealth | Read by health components and UI, not per activation. |
| Continuously sampled by a component | movement speed, gravity scale, jump velocity | The Character Movement Component samples them every frame with no ability in scope. |