Ue Specifiers
fjz13/UnrealSpecifiers
A skill your agent uses when writing, editing, reviewing, validating, or explaining Unreal Engine C++ reflected declarations: UCLASS, USTRUCT, UENUM, UINTERFACE, UPROPERTY, UFUNCTION, UPARAM, UMETA…
A skill your agent uses when implementing or debugging the Gameplay Ability System in C++ — abilities, effects, attributes, cues and the AbilitySystemComponent.
$ npx skills add quodsoler/unreal-engine-skills --skill ue-gameplay-abilities -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install quodsoler/unreal-engine-skills ue-gameplay-abilities --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/quodsoler/unreal-engine-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/ue-gameplay-abilities .claude/skills/ue-gameplay-abilities && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "ue-gameplay-abilities" agent skill from https://github.com/quodsoler/unreal-engine-skills/tree/main/skills/ue-gameplay-abilities into .claude/skills/ue-gameplay-abilities/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ue-gameplay-abilities", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/quodsoler/unreal-engine-skills/tree/main/skills/ue-gameplay-abilitiesType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add quodsoler/unreal-engine-skills --skill ue-gameplay-abilities -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install quodsoler/unreal-engine-skills ue-gameplay-abilities --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/quodsoler/unreal-engine-skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/ue-gameplay-abilities .agents/skills/ue-gameplay-abilities && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "ue-gameplay-abilities" agent skill from https://github.com/quodsoler/unreal-engine-skills/tree/main/skills/ue-gameplay-abilities into .agents/skills/ue-gameplay-abilities/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ue-gameplay-abilities", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add quodsoler/unreal-engine-skills --skill ue-gameplay-abilities -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install quodsoler/unreal-engine-skills ue-gameplay-abilities --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/quodsoler/unreal-engine-skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/ue-gameplay-abilities .cursor/skills/ue-gameplay-abilities && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "ue-gameplay-abilities" agent skill from https://github.com/quodsoler/unreal-engine-skills/tree/main/skills/ue-gameplay-abilities into .cursor/skills/ue-gameplay-abilities/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ue-gameplay-abilities", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/quodsoler/unreal-engine-skills.git --path skills/ue-gameplay-abilities--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add quodsoler/unreal-engine-skills --skill ue-gameplay-abilities -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install quodsoler/unreal-engine-skills ue-gameplay-abilities --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/quodsoler/unreal-engine-skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/ue-gameplay-abilities .gemini/skills/ue-gameplay-abilities && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "ue-gameplay-abilities" agent skill from https://github.com/quodsoler/unreal-engine-skills/tree/main/skills/ue-gameplay-abilities into .gemini/skills/ue-gameplay-abilities/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ue-gameplay-abilities", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install quodsoler/unreal-engine-skills ue-gameplay-abilitiesInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add quodsoler/unreal-engine-skills --skill ue-gameplay-abilities -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/quodsoler/unreal-engine-skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/ue-gameplay-abilities .github/skills/ue-gameplay-abilities && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "ue-gameplay-abilities" agent skill from https://github.com/quodsoler/unreal-engine-skills/tree/main/skills/ue-gameplay-abilities into .github/skills/ue-gameplay-abilities/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ue-gameplay-abilities", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add quodsoler/unreal-engine-skills --skill ue-gameplay-abilities -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install quodsoler/unreal-engine-skills ue-gameplay-abilities --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/quodsoler/unreal-engine-skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/ue-gameplay-abilities .opencode/skills/ue-gameplay-abilities && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "ue-gameplay-abilities" agent skill from https://github.com/quodsoler/unreal-engine-skills/tree/main/skills/ue-gameplay-abilities into .opencode/skills/ue-gameplay-abilities/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ue-gameplay-abilities", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
ue-gameplay-abilitiesA skill your agent uses when implementing or debugging the Gameplay Ability System in C++ — abilities, effects, attributes, cues and the AbilitySystemComponent.
Ue Gameplay Abilities is an agent skill from quodsoler/unreal-engine-skills. Use when implementing or debugging the Gameplay Ability System in C++ — abilities, effects, attributes, cues and the AbilitySystemComponent. Also use when the user mentions 'GAS', 'UGameplayAbility', 'ActivateAbility', 'CommitAbility', 'UGameplayEffect', 'UAttributeSet', 'FGameplayAttributeData', 'AbilitySystemComponent', 'InitAbilityActorInfo', 'GiveAbility', 'TryActivateAbility', 'ability task', 'GameplayCue', 'cooldown', 'cost', 'buff', 'debuff', 'damage execution' or 'ASC on PlayerState'. For montage…
Its SKILL.md is about 6.6k tokens, which your agent loads only when the skill is triggered. The skill folder holds 4 other files, including reference files (for example `references/ability-task-reference.md`, `references/gameplay-effect-reference.md` and `references/gas-setup-patterns.md`).
It sits in Databases, covering Database administration. It works with C++. The repository describes itself as: Unreal Engine C++ skills for AI coding agents. 27 skills covering gameplay, rendering, networking, animation, and more. Works with Claude Code, Cursor, Windsurf, and any agent… The licence is MIT.
Read from SKILL.md and the folder at commit f3742d7. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are cpp).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Ue Gameplay Abilities loads about 6.6k tokens when it runs, and up to ~17k if it reads all its reference files. Until then it costs about 159 tokens; SKILL.md has 1,628 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from quodsoler/unreal-engine-skills at commit f3742d7, republished under its MIT licence (© quodsoler). 1,628 words, ~6,626 tokens.
.claude/skills/ue-gameplay-abilities/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.Target engine: UE 5.8. APIs below are verified against the 5.8 headers; older forms are listed under "Deprecated — do not use".
GAS ships as the GameplayAbilities plugin (Engine/Plugins/Runtime/GameplayAbilities), which is production-ready, not Experimental. Enable it in the .uproject, then add "GameplayAbilities", "GameplayTags" and "GameplayTasks" to PublicDependencyModuleNames in your module's Build.cs. This skill covers UAbilitySystemComponent, UGameplayAbility, UGameplayEffect, UAttributeSet, UAbilityTask and Gameplay Cues.
Read .agents/ue-project-context.md if it exists (module names, conventions, enabled plugins, GAS/networking setup). Do not stop if it is missing.
Identify the area from the request and the codebase. Ask only when two plausible readings would produce different code.
| Request is about… | Go to |
|---|---|
| Where the ASC lives, init order, respawn, replication mode | ASC Ownership and Initialization |
| Writing an ability, activation, cost, cooldown, policies | Gameplay Abilities |
| Waiting on montages, events, targeting, timers, tag queries | Ability Tasks |
| Damage, buffs, stacking, executions, immunity, GE components | Gameplay Effects |
| Health/mana floats, clamping, attribute replication | Attribute Sets |
| Tags that block, grant or cancel abilities; loose tags | Tags in GAS |
| Particles, sounds, hit impacts, cue notify classes | Gameplay Cues |
| Cue scan paths, global curve tables, project config | Project Settings |
| Pillar | Class | Header | Purpose |
|---|---|---|---|
| Component | UAbilitySystemComponent | AbilitySystemComponent.h | Owns abilities, effects, attributes, tags |
| Abilities | UGameplayAbility | Abilities/GameplayAbility.h | What happens when activated |
| Effects | UGameplayEffect | GameplayEffect.h | Data-driven attribute mutation |
| Attributes | UAttributeSet | AttributeSet.h | Replicated FGameplayAttributeData stats |
| Tasks | UAbilityTask | Abilities/Tasks/AbilityTask.h | Latent steps inside an ability |
Gameplay tags thread through all of them as requirements, grants and blockers.
| Owner | When | Notes |
|---|---|---|
APlayerState | Networked player characters | ASC survives pawn death; use Mixed replication |
APawn / ACharacter | AI, single-player | Simplest; use Minimal for AI, Full if a pawn-owned ASC needs full data on all clients |
Every actor that owns or exposes an ASC implements IAbilitySystemInterface:
// MyCharacter.h
#pragma once
#include "GameFramework/Character.h"
#include "AbilitySystemInterface.h"
#include "MyCharacter.generated.h"
class UAbilitySystemComponent;
UCLASS()
class MYGAME_API AMyCharacter : public ACharacter, public IAbilitySystemInterface
{
GENERATED_BODY()
public:
AMyCharacter();
virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
protected:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "GAS")
TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent;
};// MyCharacter.cpp
#include "MyCharacter.h"
#include "AbilitySystemComponent.h"
AMyCharacter::AMyCharacter()
{
AbilitySystemComponent = CreateDefaultSubobject<UAbilitySystemComponent>(TEXT("AbilitySystemComponent"));
AbilitySystemComponent->SetIsReplicated(true);
AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Mixed);
}
UAbilitySystemComponent* AMyCharacter::GetAbilitySystemComponent() const
{
return AbilitySystemComponent;
}InitAbilityActorInfo(OwnerActor, AvatarActor) must run on both server and client. For a pawn-owned ASC that is BeginPlay with (this, this). For a PlayerState-owned ASC it is PossessedBy on the server and OnRep_PlayerState on the client, with (PlayerState, Character). Full dual-path code, respawn handling and the AI variant are in gas-setup-patterns.md.
EGameplayEffectReplicationMode | Effect on simulated proxies |
|---|---|
Minimal | No GE replication; minimal tag/cue data only. AI and non-player actors |
Mixed | Full GEs to the owning connection, minimal to everyone else. Player characters |
Full | Every GE replicates to every client |
Mixed sends full GE data to the connection that owns the ASC's owner actor (GameplayEffect.cpp:5240), so it works for a PlayerState-owned ASC and for a pawn-owned ASC once a PlayerController possesses the pawn. Choosing Full over Mixed is a bandwidth decision, not a correctness one. Minimal does not work for player-owned ASCs (AbilitySystemComponent.h:83). See ue-networking-replication for what each mode costs on the wire.
// MyFireballAbility.h
#pragma once
#include "Abilities/GameplayAbility.h"
#include "MyFireballAbility.generated.h"
class UGameplayEffect;
UCLASS()
class MYGAME_API UMyFireballAbility : public UGameplayAbility
{
GENERATED_BODY()
public:
UMyFireballAbility();
virtual bool CanActivateAbility(const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayTagContainer* SourceTags = nullptr,
const FGameplayTagContainer* TargetTags = nullptr,
OUT FGameplayTagContainer* OptionalRelevantTags = nullptr) const override;
virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo ActivationInfo,
const FGameplayEventData* TriggerEventData) override;
virtual void EndAbility(const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo ActivationInfo,
bool bReplicateEndAbility, bool bWasCancelled) override;
virtual void CancelAbility(const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo ActivationInfo,
bool bReplicateCancelAbility) override;
protected:
UPROPERTY(EditDefaultsOnly, Category = "GAS")
TSubclassOf<UGameplayEffect> DamageEffect;
};Constructor sets the policies and the ability's own tags:
// MyFireballAbility.cpp
#include "MyFireballAbility.h"
#include "AbilitySystemBlueprintLibrary.h"
#include "AbilitySystemComponent.h"
UMyFireballAbility::UMyFireballAbility()
{
InstancingPolicy = EGameplayAbilityInstancingPolicy::InstancedPerActor;
NetExecutionPolicy = EGameplayAbilityNetExecutionPolicy::LocalPredicted;
NetSecurityPolicy = EGameplayAbilityNetSecurityPolicy::ClientOrServer;
FGameplayTagContainer Tags;
Tags.AddTag(FGameplayTag::RequestGameplayTag(TEXT("Ability.Skill.Fireball")));
SetAssetTags(Tags);
ActivationOwnedTags.AddTag(FGameplayTag::RequestGameplayTag(TEXT("Ability.Active.Casting")));
ActivationBlockedTags.AddTag(FGameplayTag::RequestGameplayTag(TEXT("State.Stunned")));
CancelAbilitiesWithTag.AddTag(FGameplayTag::RequestGameplayTag(TEXT("Ability.Active.Melee")));
}SetAssetTags is constructor-only; read them back with GetAssetTags().
| Enum | Values | Use |
|---|---|---|
EGameplayAbilityInstancingPolicy | InstancedPerActor, InstancedPerExecution | InstancedPerActor is the default choice; per-execution when several copies may run at once |
EGameplayAbilityNetExecutionPolicy | LocalPredicted, LocalOnly, ServerInitiated, ServerOnly | LocalPredicted for responsive player abilities |
EGameplayAbilityNetSecurityPolicy | ClientOrServer, ServerOnlyExecution, ServerOnlyTermination, ServerOnly | Rejects client requests the server should own |
void UMyFireballAbility::ActivateAbility(const FGameplayAbilitySpecHandle Handle,
const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo ActivationInfo,
const FGameplayEventData* TriggerEventData)
{
Super::ActivateAbility(Handle, ActorInfo, ActivationInfo, TriggerEventData);
// CommitAbility applies cost and cooldown; it fails if either cannot be paid.
if (!CommitAbility(Handle, ActorInfo, ActivationInfo))
{
EndAbility(Handle, ActorInfo, ActivationInfo, true, true);
return;
}
const FGameplayEffectSpecHandle Spec =
MakeOutgoingGameplayEffectSpec(DamageEffect, GetAbilityLevel());
const FGameplayAbilityTargetDataHandle TargetData =
UAbilitySystemBlueprintLibrary::AbilityTargetDataFromActor(ActorInfo->AvatarActor.Get());
ApplyGameplayEffectSpecToTarget(Handle, ActorInfo, ActivationInfo, Spec, TargetData);
EndAbility(Handle, ActorInfo, ActivationInfo, true, false);
}Split the commit when the two halves must happen at different times: CommitAbilityCost(Handle, ActorInfo, ActivationInfo) and CommitAbilityCooldown(Handle, ActorInfo, ActivationInfo, ForceCooldown) — note the cooldown overload takes the extra const bool ForceCooldown.
Inside an instanced ability, GetAbilitySystemComponentFromActorInfo_Ensured() returns the ASC and logs an ensure instead of crashing when actor info is not set up.
Granting and activating, from the server:
const FGameplayAbilitySpecHandle Handle =
ASC->GiveAbility(FGameplayAbilitySpec(UMyFireballAbility::StaticClass(), 1));
ASC->TryActivateAbility(Handle);
ASC->TryActivateAbilityByClass(UMyFireballAbility::StaticClass());
ASC->TryActivateAbilitiesByTag(
FGameplayTagContainer(FGameplayTag::RequestGameplayTag(TEXT("Ability.Skill.Fireball"))));
ASC->ClearAbility(Handle);Ability tasks make an ability span frames. The pattern is always: static factory → bind delegates → ReadyForActivation() (inherited from UGameplayTask). Task delegates are dynamic, so each handler needs UFUNCTION():
// In the ability's header:
UFUNCTION()
void HandleMontageCompleted();
UFUNCTION()
void HandleMontageInterrupted();#include "Abilities/Tasks/AbilityTask_PlayMontageAndWait.h"
UAbilityTask_PlayMontageAndWait* Task =
UAbilityTask_PlayMontageAndWait::CreatePlayMontageAndWaitProxy(
this, NAME_None, AttackMontage, 1.f);
Task->OnCompleted.AddDynamic(this, &UMyFireballAbility::HandleMontageCompleted);
Task->OnInterrupted.AddDynamic(this, &UMyFireballAbility::HandleMontageInterrupted);
Task->ReadyForActivation();| Task | Waits for |
|---|---|
UAbilityTask_PlayMontageAndWait | An UAnimMontage to finish, blend out, interrupt or cancel |
UAbilityTask_PlayAnimAndWait | A raw UAnimSequence played into a slot, for linked anim layers |
UAbilityTask_WaitGameplayEvent | A gameplay event tag sent to the ASC (anim notify, hit registration) |
UAbilityTask_WaitDelay | A fixed number of seconds |
UAbilityTask_WaitTargetData | An AGameplayAbilityTargetActor to confirm targets |
UAbilityTask_WaitAttributeChange / ...ChangeThreshold | An attribute to change or cross a comparison |
UAbilityTask_WaitGameplayTagQuery | An FGameplayTagQuery over the target's tags to become true or false |
UAbilityTask_WaitGameplayTagCountChanged | The count of one tag on the ASC to change |
UAbilityTask_WaitGameplayEffectApplied_Self / _Target | A GE matching tag requirements (or an FGameplayTagQuery via the _Query factories) |
Full factory signatures, delegate names, the custom-task template and the task pitfalls are in ability-task-reference.md.
EGameplayEffectDurationType | Behaviour |
|---|---|
Instant | Executes once against the base value; fires PostGameplayEffectExecute |
HasDuration | Aggregates onto the current value for DurationMagnitude seconds |
Infinite | Aggregates until removed explicitly |
const FGameplayEffectContextHandle Ctx = ASC->MakeEffectContext();
const FGameplayEffectSpecHandle Spec =
ASC->MakeOutgoingSpec(UMyDamageEffect::StaticClass(), Level, Ctx);
Spec.Data->SetSetByCallerMagnitude(
FGameplayTag::RequestGameplayTag(TEXT("SetByCaller.Damage")), 75.f);
ASC->ApplyGameplayEffectSpecToSelf(*Spec.Data.Get());
ASC->ApplyGameplayEffectSpecToTarget(*Spec.Data.Get(), TargetASC);
ASC->RemoveActiveGameplayEffect(ActiveHandle);
ASC->RemoveActiveGameplayEffectBySourceEffect(UMyDamageEffect::StaticClass(), nullptr);Modifier ops live in EGameplayModOp (a namespaced enum, so values are TEnumAsByte<EGameplayModOp::Type>). The aggregation equation is
((BaseValue + AddBase) * MultiplyAdditive / DivideAdditive * MultiplyCompound) + AddFinal.
| Value | Meaning |
|---|---|
AddBase | Added to the base before anything else |
MultiplyAdditive | Multipliers summed, then multiplied against the running result |
DivideAdditive | Divisors summed, then divided against the running result |
MultiplyCompound | Multiplied into the running result, compounding with other compounds |
AddFinal | Added after all multiplication |
Override | Replaces the computed value |
Behaviour that used to be monolithic properties on UGameplayEffect now lives in UGameplayEffectComponent subclasses under GameplayEffectComponents/. Stacking, magnitude calculations, UGameplayEffectExecutionCalculation, periodic effects, immunity, queries, lifecycle delegates and the full component list are in gameplay-effect-reference.md.
// MyHealthSet.h
#pragma once
#include "AttributeSet.h"
#include "AbilitySystemComponent.h"
#include "MyHealthSet.generated.h"
UCLASS()
class MYGAME_API UMyHealthSet : public UAttributeSet
{
GENERATED_BODY()
public:
UMyHealthSet();
virtual void PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue) override;
virtual void PostGameplayEffectExecute(const struct FGameplayEffectModCallbackData& Data) override;
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Health, Category = "Health")
FGameplayAttributeData Health;
ATTRIBUTE_ACCESSORS_BASIC(UMyHealthSet, Health)
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_MaxHealth, Category = "Health")
FGameplayAttributeData MaxHealth;
ATTRIBUTE_ACCESSORS_BASIC(UMyHealthSet, MaxHealth)
protected:
UFUNCTION()
void OnRep_Health(const FGameplayAttributeData& OldHealth);
UFUNCTION()
void OnRep_MaxHealth(const FGameplayAttributeData& OldMaxHealth);
};ATTRIBUTE_ACCESSORS_BASIC generates GetHealthAttribute(), GetHealth(), SetHealth() and InitHealth(). Projects that want extra accessors define their own macro chaining GAMEPLAYATTRIBUTE_PROPERTY_GETTER, GAMEPLAYATTRIBUTE_VALUE_GETTER, GAMEPLAYATTRIBUTE_VALUE_SETTER and GAMEPLAYATTRIBUTE_VALUE_INITTER.
Each OnRep_ body is one GAMEPLAYATTRIBUTE_REPNOTIFY(UMyHealthSet, Health, OldHealth) call, and every attribute needs a DOREPLIFETIME_CONDITION_NOTIFY(UMyHealthSet, Health, COND_None, REPNOTIFY_Always) line. The full .cpp with clamping is in gas-setup-patterns.md.
| Hook | Fires | Use for |
|---|---|---|
PreAttributeChange | Every current-value recompute | Clamping the current value only |
PreAttributeBaseChange | Before a base-value write (const) | Clamping the base value |
PostGameplayEffectExecute | After an instant GE, or one period of a periodic GE, writes the base value | Death, hit reactions, game events |
PostAttributeChange | After a current value changed | Reacting to derived state |
Registering and reading:
// Constructor of the ASC owner — the ASC finds subobject attribute sets automatically:
HealthSet = CreateDefaultSubobject<UMyHealthSet>(TEXT("HealthSet"));
// Runtime, authority only:
UMyHealthSet* NewSet = NewObject<UMyHealthSet>(this);
ASC->AddSpawnedAttribute(NewSet);
const float CurrentHealth = ASC->GetNumericAttribute(UMyHealthSet::GetHealthAttribute());One ASC can host several UAttributeSet subclasses, but only one instance per class.
Tag definition (native tag macros, .ini tag sources), container matching and FGameplayTagQuery semantics belong to ue-gameplay-tags-messaging. What is GAS-specific:
// On the ability CDO (constructor): tags granted while the ability runs, and the gates.
ActivationOwnedTags.AddTag(CastingTag);
ActivationRequiredTags.AddTag(WeaponEquippedTag);
ActivationBlockedTags.AddTag(StunnedTag);
BlockAbilitiesWithTag.AddTag(MeleeTag);
CancelAbilitiesWithTag.AddTag(ChannelTag);
// On the ASC: query and react.
ASC->HasMatchingGameplayTag(StunnedTag);
const FGameplayTagContainer& Owned = ASC->GetOwnedGameplayTags();
ASC->RegisterGameplayTagEvent(StunnedTag, EGameplayTagEventType::NewOrRemoved)
.AddUObject(this, &AMyCharacter::HandleStunnedTagChanged);The callback is declared as void HandleStunnedTagChanged(const FGameplayTag Tag, int32 NewCount); and needs no UFUNCTION() — tag events are plain multicast delegates.
Loose tags are set directly instead of through a GE. The third argument chooses how the tag replicates:
ASC->AddLooseGameplayTag(StunnedTag); // local only
ASC->AddLooseGameplayTag(BuffedTag, 1, EGameplayTagReplicationState::TagOnly); // tag to all
ASC->AddLooseGameplayTag(BuffedTag, 1, EGameplayTagReplicationState::CountToOwner);// + count to owner
ASC->RemoveLooseGameplayTag(BuffedTag, 1, EGameplayTagReplicationState::TagOnly);
ASC->SetLooseGameplayTagCount(BuffedTag, 3, EGameplayTagReplicationState::TagAndCountToAll);EGameplayTagReplicationState values: None, SimulatedTagOnly, TagOnly, CountToOwner, TagAndCountToAll. Anything other than None must be added on the server.
Cues are cosmetic only. Tag prefix GameplayCue.; a GE triggers them through its GameplayCues array, or code fires them directly:
ASC->ExecuteGameplayCue(HitCueTag, ASC->MakeEffectContext()); // one-shot
ASC->AddGameplayCue(BuffCueTag); // persistent
ASC->RemoveGameplayCue(BuffCueTag);
const bool bActive = ASC->IsGameplayCueActive(BuffCueTag);| Class | Base | Override | Use |
|---|---|---|---|
UGameplayCueNotify_Static | UObject | OnExecute_Implementation | Burst cue with no spawned actor |
UGameplayCueNotify_Burst | UGameplayCueNotify_Static | data-driven burst effects | One-shot particles/sounds, no code |
UGameplayCueNotify_HitImpact | UGameplayCueNotify_Static | data-driven impact effects | Surface-typed impacts |
AGameplayCueNotify_Actor | AActor | OnActive_/WhileActive_/OnRemove_Implementation | Persistent cue needing an actor |
AGameplayCueNotify_BurstLatent | AGameplayCueNotify_Actor | data-driven burst effects | Burst that must spawn an actor |
AGameplayCueNotify_Looping | AGameplayCueNotify_Actor | data-driven looping effects | Looping auras and channels |
// MyHitCue.h
#pragma once
#include "GameplayCueNotify_Static.h"
#include "MyHitCue.generated.h"
UCLASS()
class MYGAME_API UMyHitCue : public UGameplayCueNotify_Static
{
GENERATED_BODY()
public:
virtual bool OnExecute_Implementation(AActor* MyTarget,
const FGameplayCueParameters& Parameters) const override;
};UGameplayCueManager discovers cue assets under the scan paths configured in project settings.
GAS configuration is a UDeveloperSettings class: UGameplayAbilitiesDeveloperSettings (Project Settings → Gameplay Abilities). Read it with GetDefault<UGameplayAbilitiesDeveloperSettings>(). Notable fields: GameplayCueNotifyPaths, ReplicateActivationOwnedTags, bAllowGameplayModEvaluationChannels, plus the global curve/attribute tables. Runtime helpers stay on UAbilitySystemGlobals (GetGameplayCueNotifyPaths(), AddGameplayCueNotifyPath(), GetAttributeSetInitter()).
| Do not emit | Use in 5.8 | Source |
|---|---|---|
AGameplayCueNotify_Static | UGameplayCueNotify_Static (a UObject) | Class never existed; GameplayCueNotify_Static.h:19 |
EGameplayModOp::Multiplicative | EGameplayModOp::MultiplyAdditive (legacy alias is spelled Multiplicitive) | GameplayEffectTypes.h:112-148 |
EGameplayModOp::Additive / Division | AddBase / DivideAdditive | Hidden back-compat aliases, GameplayEffectTypes.h:141-143 |
EGameplayAbilityInstancingPolicy::NonInstanced | InstancedPerActor | UE_DEPRECATED_FORGAME(5.5) in Abilities/GameplayAbilityTypes.h:46 |
UGameplayAbility::AbilityTags | GetAssetTags() / SetAssetTags() | UE_DEPRECATED_FORGAME(5.5) in Abilities/GameplayAbility.h:474 |
GetAbilitySystemComponentFromActorInfo_Checked() | GetAbilitySystemComponentFromActorInfo_Ensured() | UE_DEPRECATED(5.5) in Abilities/GameplayAbility.h:168 |
NetUpdateFrequency assignment on an actor | SetNetUpdateFrequency(100.f) | UE_DEPRECATED(5.5) in GameFramework/Actor.h:903 |
UGameplayEffect::StackingType (public read) | GetStackingType() | UE_DEPRECATED(5.7) in GameplayEffect.h:2407 |
UGameplayEffect::GrantedApplicationImmunityTags | UImmunityGameplayEffectComponent | UE_DEPRECATED(5.3) in GameplayEffect.h:2379 |
AddReplicatedLooseGameplayTag | AddLooseGameplayTag(Tag, Count, EGameplayTagReplicationState::CountToOwner) (the deprecation message's replacement; TagOnly if no client needs the count) | Function removed (no declaration in 5.8); the backing ReplicatedLooseTags member is UE_DEPRECATED(5.7) at AbilitySystemComponent.h:1941 |
FGameplayAbilitySpec::DynamicAbilityTags | GetDynamicSpecSourceTags() | UE_DEPRECATED(5.5) in GameplayAbilitySpec.h:242 |
UAbilitySystemBlueprintLibrary::MakeSpecHandle | MakeSpecHandleByClass | UE_DEPRECATED(5.5) in AbilitySystemBlueprintLibrary.h:249 |
UAbilitySystemGlobals config members | GetDefault<UGameplayAbilitiesDeveloperSettings>() | UE_DEPRECATED(5.5) throughout AbilitySystemGlobals.h |
FGameplayEffectSpec::GetModifierMagnitude(ModifierIdx, bFactorInStackCount) | GetModifierMagnitude(int32 ModifierIdx) | UE_DEPRECATED(5.6) in GameplayEffect.h:1153 |
FActiveGameplayEffectHandle(int32), ResetGlobalHandleMap(), RemoveFromGlobalMap() | FActiveGameplayEffectHandle::GenerateNewHandle() or GetInstantExecutedHandle(); the global map is gone | UE_DEPRECATED(5.8) in ActiveGameplayEffectHandle.h:30,66,69 |
Implementing IAbilitySystemInterface only on the pawn: when the ASC lives on the PlayerState, the PlayerState must implement the interface too, otherwise UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent fails on the owner.
Calling InitAbilityActorInfo only on the server: clients need it as well. Server path is PossessedBy, client path is OnRep_PlayerState. Without the client call, attribute change delegates never fire on the owning client.
Applying GEs before init: granting abilities or applying effects before InitAbilityActorInfo runs leaves the ASC without actor info and the attribute sets unregistered.
Clamping in the wrong hook: PreAttributeChange fires on every aggregator recompute, so it may only clamp NewValue. Death, hit reactions and gameplay events belong in PostGameplayEffectExecute, which only runs for executions (instant GEs and periodic ticks).
Forgetting CommitAbility: the ability runs, but no cost is paid and no cooldown starts.
Assuming loose tags replicate: AddLooseGameplayTag(Tag) defaults to EGameplayTagReplicationState::None. Pass TagOnly or CountToOwner from the server, or grant the tag through a GE.
Stacks silently capped: applications beyond GetStackLimitCount() are rejected without an error. Check GetCurrentStackCount(Handle) before assuming a stack landed.
Startup effects in BeginPlay without an authority check: late joiners re-apply them. Gate every GiveAbility and startup GE behind HasAuthority().
AI with no PlayerState: put the ASC on the AI character, call InitAbilityActorInfo(this, this) and set Minimal replication.
ue-gameplay-tags-messaging — tag definition (native tag macros, ini tag sources), containers, FGameplayTagQuery and gameplay messagingue-networking-replication — DOREPLIFETIME variants, RPCs, prediction keys, push modelue-animation-system — montage assets, notifies and slots that the montage ability tasks driveue-character-movement — movement modes that root-motion ability tasks manipulateue-cpp-foundations — UPROPERTY/UFUNCTION specifiers, delegates, TSubclassOf, subsystemsue-data-assets-tables — UCurveTable and UDataTable assets behind attribute initialisation and FScalableFloatue-state-trees — running abilities from State Tree tasksue-actor-component-architecture — component creation, subobject registration, replication of subobjectsue-gameplay-framework — PlayerState and Pawn lifecycle, and damage without GAS (TakeDamage, UDamageType)ue-input-system — Enhanced Input actions bound to ability input idsue-game-features — granting abilities and attribute sets from a game feature pluginue-niagara-effects — Niagara systems, user parameters, data interfaces and data channelsue-ui-umg-slate — UMG widgets, Slate, Common UI and MVVM© quodsoler, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 3 other files (references) in skills/ue-gameplay-abilities of quodsoler/unreal-engine-skills.
Open the folder on GitHubat commit f3742d7
Ue Gameplay Abilities next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Ue Gameplay Abilities this skillquodsoler/unreal-engine-skills | 362 | — | ~6.6k | Automated safety check: Pass | MIT | |
| Ue Specifiersfjz13/UnrealSpecifiers | 1.1k | — | ~1.4k | Automated safety check: Pass | Custom licence | |
| Triage Tt Metal Assertstenstorrent/tt-mlir | 314 | — | ~7.8k | Automated safety check: Pass | Apache-2.0 | |
| Tlaplus Spec GeneratorArabelaTso/Skills-4-SE | 253 | — | ~2.3k | Automated safety check: Pass | Apache-2.0 | |
| Hybrid Cloud Outboxesgetsentry/sentry | 46k | — | ~4.8k | Automated safety check: Pass | Custom licence | |
| Elodin DBelodin-sys/elodin | 547 | — | ~2.9k | Automated safety check: Pass | Apache-2.0 |
fjz13/UnrealSpecifiers
A skill your agent uses when writing, editing, reviewing, validating, or explaining Unreal Engine C++ reflected declarations: UCLASS, USTRUCT, UENUM, UINTERFACE, UPROPERTY, UFUNCTION, UPARAM, UMETA…
tenstorrent/tt-mlir
Triage a tt-metal uplift diff or digest of TTFATAL validation changes against what tt-mlir guarantees at each optimization level (0: workarounds only, 1: optimizer with DRAM-only fallback, 2: L1…
ArabelaTso/Skills-4-SE
Automatically generate TLA+ specifications from source code (C/C++, Python) for formal verification of distributed systems.
getsentry/sentry
Guide for creating and maintaining outbox-based eventually consistent operations in Sentry.
elodin-sys/elodin
Work with Elodin-DB, the time-series telemetry database. An agent skill from elodin-sys/elodin.
majiayu000/litellm-rs
LiteLLM-RS provider system in two tiers - data-driven OpenAI-compatible catalog entries auto-routed through OpenAILikeProvider, plus code-based provider modules implementing the LLMProvider trait…
quodsoler/unreal-engine-skills
Unreal Engine C++ guidance for AActor and UActorComponent: lifecycle hooks, spawning, component creation and attachment, ticking, interfaces and composition.
quodsoler/unreal-engine-skills
Guides Unreal Engine C++ AI work across AI controllers, behavior trees, blackboards, perception, navmesh pathfinding, EQS and Smart Objects.
quodsoler/unreal-engine-skills
Reference for writing and debugging Unreal Engine 5.8 animation C++: AnimInstance and proxy, montages, notifies, curves, blend spaces, state machines, linked layers and root motion.
quodsoler/unreal-engine-skills
Picks and applies the right Unreal Engine C++ concurrency API, from UE::Tasks and FPipe to ParallelFor, FRunnable, locks and timers, with game-thread safety rules.
quodsoler/unreal-engine-skills
A skill your agent uses when playing, mixing or debugging sound in Unreal Engine — one-shot SFX, looping ambience, music, dialogue or procedural audio.
quodsoler/unreal-engine-skills
Reference for exposing Unreal Engine C++ to Blueprint and calling Blueprint from C++, covering UFUNCTION and UPROPERTY specifiers, latent and async nodes, and interfaces.
Works with
Categories
A skill your agent uses when implementing or debugging the Gameplay Ability System in C++ — abilities, effects, attributes, cues and the AbilitySystemComponent. Ue Gameplay Abilities is an agent skill from quodsoler/unreal-engine-skills. Use when implementing or debugging the Gameplay Ability System in C++ — abilities, effects, attributes, cues and the AbilitySystemComponent.
Ue Gameplay Abilities fits situations like: debugging the Gameplay Ability System in C++ — abilities; cues and the AbilitySystemComponent; the user mentions GAS; UGameplayAbility.
Run `npx skills add quodsoler/unreal-engine-skills --skill ue-gameplay-abilities -a claude-code`. Or copy the skill folder (skills/ue-gameplay-abilities in quodsoler/unreal-engine-skills) into .claude/skills/ue-gameplay-abilities in your project. Claude Code loads it when a task matches its description.
Run `npx skills add quodsoler/unreal-engine-skills --skill ue-gameplay-abilities -a codex`. Or copy the skill folder (skills/ue-gameplay-abilities in quodsoler/unreal-engine-skills) into .agents/skills/ue-gameplay-abilities in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add quodsoler/unreal-engine-skills --skill ue-gameplay-abilities -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/ue-gameplay-abilities, .gemini/skills/ue-gameplay-abilities, .github/skills/ue-gameplay-abilities and .opencode/skills/ue-gameplay-abilities in your project.
SKILL.md names no scripts, command-line tools or credentials: Ue Gameplay Abilities is instructions for the agent only.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Ue Gameplay Abilities is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 6.6k tokens (SKILL.md is roughly 27k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 10k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Ue Gameplay Abilities: Ue Specifiers (fjz13/UnrealSpecifiers, 1.1k stars), Triage Tt Metal Asserts (tenstorrent/tt-mlir, 314 stars), Tlaplus Spec Generator (ArabelaTso/Skills-4-SE, 253 stars) and Hybrid Cloud Outboxes (getsentry/sentry, 46k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
quodsoler (a GitHub user) maintains it in quodsoler/unreal-engine-skills, which has 362 GitHub stars. The repository holds 31 skills in this directory. The repository was last updated on September 28, 2026.
Source: quodsoler/unreal-engine-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.