Troubleshooting¶
Symptom → likely cause → fix. Jump to whatever matches your problem.
Ability Won't Activate¶
Symptom: TryActivateAbility returns false. Nothing happens when the player presses the button.
Check in order:
-
Is the ability granted? Use
showdebug abilitysystem-- the ability must appear in the ability list. If not, callGiveAbilityfirst. -
Activation Blocked Tags? The ASC might have a tag that blocks this ability. Check
ActivationBlockedTagson the ability vs the ASC's current tags. -
Activation Required Tags? The ASC might be missing a required tag.
-
On cooldown? Check Active Effects for the cooldown GE. If it's still active, the cooldown hasn't expired.
-
Can't afford cost? Check the attribute value vs the cost GE's modifier. If stamina is 15 and the cost is 20, the ability won't commit.
-
Wrong Net Execution Policy?
ServerOnlyabilities won't activate from client input.LocalOnlyabilities won't trigger server-side effects. -
CanActivateAbility override? If you've overridden
CanActivateAbilityin C++, add logging to see which check fails.
Effect Doesn't Modify Attribute¶
Symptom: The Gameplay Effect is applied (it shows up in Active Effects) but the attribute doesn't change.
Check:
-
Modifier targets the wrong attribute. Double-check the attribute reference in the modifier. Typos in the attribute set class or attribute name are silent failures.
-
Magnitude is zero. If using SetByCaller, did you actually set the value? The warning
"SetByCaller Magnitude was not set"appears in the log. If using a Curve Table, is the row name correct? If using an MMC, does it return non-zero? -
Tag requirements on the modifier. Modifiers can have source/target tag requirements. If the tags don't match, the modifier is skipped during evaluation (it's still "active" but contributes 0).
-
Wrong modifier operation.
Multiply Additivewith a value of20means +2000%. You probably wanted0.2for +20%. See Modifier Formula. -
Attribute not on the target. If the target's ASC doesn't have the AttributeSet containing that attribute, the modifier silently does nothing.
SetByCaller Is Always 0¶
Symptom: The effect applies but the magnitude from SetByCaller is 0.
Cause: The tag used in SetSetByCallerMagnitude doesn't match the tag configured on the GE modifier.
Fix:
- Check the tag on the GE modifier's magnitude: it should be something like
SetByCaller.Damage - Check your code:
SpecHandle.Data->SetSetByCallerMagnitude(Tag, Value)-- is the tag identical? - Enable verbose logging -- the system warns when a SetByCaller value is requested but wasn't set
- Common mistake: setting the value on the wrong spec handle (e.g., creating a new spec after setting the value)
Cooldown Not Working¶
Symptom: The ability can be activated repeatedly with no cooldown.
Check:
- Cooldown GE assigned? On the ability's Class Defaults, is the
CooldownGameplayEffectClassset? - Cooldown GE has correct tag? The cooldown GE must grant a tag that matches the ability's cooldown query. By default, the system checks for any tag granted by the cooldown GE.
- Duration set? The cooldown GE must have
Duration Policy = Has Durationwith a non-zero duration. - CommitAbility called? If you're handling activation manually, you must call
CommitAbility(orCommitExecute) to apply the cooldown.
Duration Buff Doesn't Undo When It Expires¶
Symptom: A Duration GE expires, but the attribute modifier persists.
Check:
- Is it actually a Duration GE? Check that
Duration Policy = Has Duration, notInstant. Instant effects permanently change the base value -- they don't revert. - Is something reapplying it? Another effect or ability might be reapplying the same modifier.
- Stacking misconfiguration. If stacking is set to
Remove Single Stack, and there are multiple stacks, only one stack is removed on expiry. - Clamping in PreAttributeChange. If you're clamping in
PreAttributeChange, it might set a "floor" that prevents the attribute from reverting to a lower base value.
Tags Don't Block / Aren't Working¶
Symptom: Tag-based blocking or requirements seem to be ignored.
Check:
- Typo in tag name. Tags are case-sensitive and hierarchy-sensitive.
CrowdControl.Stunis not the same asCrowdcontrol.StunorCC.Stun. - Tag not registered. If the tag doesn't exist in the project's tag table, it's invalid. Check Project Settings > Gameplay Tags.
- Tag query direction. Are you checking for the tag on the right actor?
ActivationBlockedTagschecks the owning ASC's tags.TargetTagRequirementson a GE checks the target's tags. - Tag count mismatch. If two effects grant the same tag, removing one effect doesn't remove the tag -- it decrements the count. The tag is only fully removed when the count reaches 0.
- Hierarchy mismatch. Checking for
CrowdControlmatchesCrowdControl.Stun(child matches parent). But checking forCrowdControl.Stundoes NOT matchCrowdControl(parent doesn't match child).
Cue Doesn't Play¶
Symptom: The effect applies, the attribute changes, but no VFX/SFX.
Check:
- Cue tag matches? The tag on the GE's GameplayCue component must match the tag on the cue notify asset. Exactly.
- Cue in scan path? The cue asset's folder must be in
GameplayCueNotifyPaths. Check Project Settings > Gameplay Abilities. - Cue loaded? Check the log for
"Missing gameplay cue handler". If the cue isn't loaded, it won't play. - Suppressed? If
ShouldSuppressGameplayCuesreturns true for the target actor, all cues are silently dropped. - Local vs replicated? A replicated cue on a simulated proxy won't play if the proxy doesn't have the ASC configured for cue handling.
- Effect is Instant? Instant effects trigger
Executecues. Duration effects triggerAdd/Removecues. Make sure the cue handles the right event type.
Compile Errors¶
"cannot open include file: *.generated.h"¶
Cause: The .generated.h file is auto-generated by Unreal Header Tool (UHT). It doesn't exist until you compile.
Fix: Build the project. If the error persists, check for syntax errors in the header file above the GENERATED_BODY() macro -- UHT will fail silently and not generate the file.
"unresolved external symbol"¶
Cause: You're using a GAS class but haven't linked the module.
Fix: Add "GameplayAbilities", "GameplayTags", and "GameplayTasks" to your module's Build.cs:
PublicDependencyModuleNames.AddRange(new string[]
{
"GameplayAbilities",
"GameplayTags",
"GameplayTasks"
});
"ATTRIBUTE_ACCESSORS undeclared identifier"¶
Cause: Missing include.
Fix: Include "AttributeSet.h" in your attribute set header. The ATTRIBUTE_ACCESSORS macro is defined there.
AttributeSet Is Null¶
Symptom: GetSet<UMyAttributeSet>() returns null. Attribute modifications crash.
Check:
- Is the AttributeSet a subobject of the ASC's owner? AttributeSets must be created as subobjects (usually
CreateDefaultSubobjectin the character/player state constructor) of the actor that owns the ASC, or registered manually. - Is the ASC initialized?
InitAbilityActorInfomust be called before accessing attribute sets. - Wrong ASC? If the ASC is on the PlayerState but you're checking the Pawn's ASC, you'll get null. Make sure
IAbilitySystemInterface::GetAbilitySystemComponent()returns the right ASC. - Timing issue? In multiplayer, the ASC and its attribute sets might not be ready immediately on
BeginPlay. UseOnAbilitySystemInitializedor a similar delegate.
Prediction Feels Wrong¶
Symptom: Ability activates but there's a visible delay, rubber-banding, or double-triggering of effects.
Check:
- Net Execution Policy: Must be
LocalPredictedfor predicted abilities - Replication Mode:
MixedorFullfor predicted abilities (notMinimalwithout extra work) - Effects outside prediction window: Any effect applied after
ActivateAbilityreturns (timers, delays) won't be predicted - ExecCalc prediction: Execution Calculations are server-only. The client can't predict the calculated value.
- Double cues: If you see a cue play twice (once predicted, once from server), the prediction key matching might be failing. Check that the GE has a valid prediction key.
Related Pages¶
- ShowDebug AbilitySystem -- visual state inspection
- Logging -- enabling verbose logs
- Prediction -- understanding prediction behavior
- Modifier Formula -- verifying modifier math