claude-code-arcane 2.3.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/README.md +131 -41
- package/agents/game/ue-blueprint-specialist.md +125 -0
- package/agents/game/ue-gas-specialist.md +133 -0
- package/agents/game/ue-umg-specialist.md +131 -0
- package/dist/cli.js +642 -478
- package/docs/SKILLS-CATALOG.md +42 -3
- package/docs/USER-GUIDE.md +28 -54
- package/hooks/detect-unreal.sh +90 -0
- package/package.json +2 -1
- package/profiles/agile.yaml +1 -1
- package/profiles/ai.yaml +1 -1
- package/profiles/android-native.yaml +1 -1
- package/profiles/audio.yaml +1 -1
- package/profiles/backend-dotnet.yaml +1 -1
- package/profiles/backend-go.yaml +1 -1
- package/profiles/backend-nestjs.yaml +1 -1
- package/profiles/backend-nextjs.yaml +1 -1
- package/profiles/backend-ts.yaml +1 -1
- package/profiles/business.yaml +1 -1
- package/profiles/clevel.yaml +1 -1
- package/profiles/clickup.yaml +1 -1
- package/profiles/core.yaml +1 -1
- package/profiles/database.yaml +1 -1
- package/profiles/design.yaml +1 -1
- package/profiles/docs.yaml +1 -1
- package/profiles/ecommerce.yaml +1 -1
- package/profiles/finance.yaml +1 -1
- package/profiles/flutter.yaml +1 -1
- package/profiles/freelance.yaml +1 -1
- package/profiles/frontend.yaml +1 -1
- package/profiles/infra.yaml +1 -1
- package/profiles/integrations.yaml +1 -1
- package/profiles/ios-native.yaml +1 -1
- package/profiles/jira.yaml +1 -1
- package/profiles/job-hunt.yaml +1 -1
- package/profiles/marketing.yaml +1 -1
- package/profiles/mobile.yaml +1 -1
- package/profiles/regulatory.yaml +1 -1
- package/profiles/second-brain.yaml +1 -1
- package/profiles/security.yaml +1 -1
- package/profiles/self-improving.yaml +1 -1
- package/profiles/statusline.yaml +1 -1
- package/profiles/testing.yaml +1 -1
- package/profiles/unity-design.yaml +1 -1
- package/profiles/unity-dev.yaml +1 -1
- package/profiles/unreal-dev.yaml +97 -0
- package/profiles/visual-novel.yaml +1 -1
- package/rules/gamedev/unreal-code.md +125 -0
- package/skills/arcane-list/SKILL.md +12 -7
- package/skills/install-mcp/SKILL.md +135 -46
- package/skills/install-mcp/references/unreal-operations.md +55 -0
- package/skills/ue-actor-component-architecture/SKILL.md +509 -0
- package/skills/ue-actor-component-architecture/references/actor-lifecycle.md +301 -0
- package/skills/ue-actor-component-architecture/references/component-types.md +592 -0
- package/skills/ue-ai-navigation/SKILL.md +526 -0
- package/skills/ue-ai-navigation/references/behavior-tree-patterns.md +392 -0
- package/skills/ue-ai-navigation/references/behavior-tree-workflow.md +107 -0
- package/skills/ue-ai-navigation/references/custom-bttask.md +104 -0
- package/skills/ue-ai-navigation/references/eqs-reference.md +423 -0
- package/skills/ue-animation-system/SKILL.md +521 -0
- package/skills/ue-animation-system/references/anim-notify-reference.md +486 -0
- package/skills/ue-animation-system/references/locomotion-setup.md +550 -0
- package/skills/ue-async-threading/SKILL.md +433 -0
- package/skills/ue-async-threading/references/thread-safety-guide.md +213 -0
- package/skills/ue-async-threading/references/threading-patterns.md +345 -0
- package/skills/ue-audio-system/SKILL.md +527 -0
- package/skills/ue-audio-system/references/audio-setup-patterns.md +700 -0
- package/skills/ue-blueprints/SKILL.md +134 -0
- package/skills/ue-blueprints/references/communication.md +82 -0
- package/skills/ue-character-movement/SKILL.md +475 -0
- package/skills/ue-character-movement/references/cmc-extension-patterns.md +335 -0
- package/skills/ue-character-movement/references/movement-pipeline.md +189 -0
- package/skills/ue-cpp-foundations/SKILL.md +533 -0
- package/skills/ue-cpp-foundations/references/components-and-gc.md +107 -0
- package/skills/ue-cpp-foundations/references/container-patterns.md +544 -0
- package/skills/ue-cpp-foundations/references/delegate-patterns.md +497 -0
- package/skills/ue-cpp-foundations/references/gameplay-classes-cpp.md +136 -0
- package/skills/ue-cpp-foundations/references/property-specifiers.md +306 -0
- package/skills/ue-data-assets-tables/SKILL.md +527 -0
- package/skills/ue-data-assets-tables/references/asset-loading-patterns.md +306 -0
- package/skills/ue-data-assets-tables/references/data-driven-design.md +378 -0
- package/skills/ue-editor-tools/SKILL.md +523 -0
- package/skills/ue-editor-tools/references/detail-customization-patterns.md +395 -0
- package/skills/ue-editor-tools/references/editor-module-setup.md +480 -0
- package/skills/ue-game-features/SKILL.md +477 -0
- package/skills/ue-game-features/references/experience-system.md +222 -0
- package/skills/ue-game-features/references/game-feature-patterns.md +308 -0
- package/skills/ue-gameplay-abilities/SKILL.md +518 -0
- package/skills/ue-gameplay-abilities/references/ability-task-reference.md +391 -0
- package/skills/ue-gameplay-abilities/references/gameplay-effect-reference.md +397 -0
- package/skills/ue-gameplay-abilities/references/gas-setup-patterns.md +369 -0
- package/skills/ue-gameplay-framework/SKILL.md +466 -0
- package/skills/ue-gameplay-framework/references/framework-class-map.md +243 -0
- package/skills/ue-input-system/SKILL.md +394 -0
- package/skills/ue-input-system/references/cpp-setup.md +131 -0
- package/skills/ue-input-system/references/enhanced-input-workflow.md +117 -0
- package/skills/ue-input-system/references/input-action-reference.md +731 -0
- package/skills/ue-mass-entity/SKILL.md +476 -0
- package/skills/ue-mass-entity/references/mass-entity-patterns.md +319 -0
- package/skills/ue-mass-entity/references/mass-fragment-reference.md +119 -0
- package/skills/ue-materials-rendering/SKILL.md +526 -0
- package/skills/ue-materials-rendering/references/material-parameter-reference.md +216 -0
- package/skills/ue-materials-rendering/references/post-process-settings.md +383 -0
- package/skills/ue-module-build-system/SKILL.md +487 -0
- package/skills/ue-module-build-system/references/build-cs-reference.md +418 -0
- package/skills/ue-module-build-system/references/common-build-errors.md +381 -0
- package/skills/ue-naming-conventions/SKILL.md +142 -0
- package/skills/ue-naming-conventions/references/asset-name-modifiers.md +233 -0
- package/skills/ue-naming-conventions/references/content-structure.md +83 -0
- package/skills/ue-networking-replication/SKILL.md +452 -0
- package/skills/ue-networking-replication/references/replication-patterns.md +526 -0
- package/skills/ue-networking-replication/references/rpc-decision-guide.md +393 -0
- package/skills/ue-niagara-effects/SKILL.md +531 -0
- package/skills/ue-niagara-effects/references/niagara-data-interfaces.md +491 -0
- package/skills/ue-niagara-effects/references/niagara-parameter-types.md +153 -0
- package/skills/ue-niagara-effects/references/niagara-workflow.md +115 -0
- package/skills/ue-packaging/SKILL.md +116 -0
- package/skills/ue-physics-collision/SKILL.md +423 -0
- package/skills/ue-physics-collision/references/collision-channel-setup.md +218 -0
- package/skills/ue-physics-collision/references/trace-patterns.md +499 -0
- package/skills/ue-procedural-generation/SKILL.md +505 -0
- package/skills/ue-procedural-generation/references/pcg-node-reference.md +381 -0
- package/skills/ue-procedural-generation/references/procedural-mesh-patterns.md +940 -0
- package/skills/ue-project-context/SKILL.md +305 -0
- package/skills/ue-sequencer-cinematics/SKILL.md +506 -0
- package/skills/ue-sequencer-cinematics/references/sequencer-patterns.md +629 -0
- package/skills/ue-serialization-savegames/SKILL.md +524 -0
- package/skills/ue-serialization-savegames/references/save-system-architecture.md +705 -0
- package/skills/ue-state-trees/SKILL.md +489 -0
- package/skills/ue-state-trees/references/state-tree-mass-integration.md +184 -0
- package/skills/ue-state-trees/references/state-tree-patterns.md +321 -0
- package/skills/ue-testing-debugging/SKILL.md +520 -0
- package/skills/ue-testing-debugging/references/automation-test-patterns.md +387 -0
- package/skills/ue-testing-debugging/references/profiling-commands.md +357 -0
- package/skills/ue-ui-umg-slate/SKILL.md +431 -0
- package/skills/ue-ui-umg-slate/references/common-ui-setup.md +484 -0
- package/skills/ue-ui-umg-slate/references/widget-types.md +487 -0
- package/skills/ue-world-level-streaming/SKILL.md +518 -0
- package/skills/ue-world-level-streaming/references/streaming-patterns.md +414 -0
- package/templates/gamedev/unreal-project-context.md +107 -0
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
# GameplayEffect Reference
|
|
2
|
+
|
|
3
|
+
Configuration guide for `UGameplayEffect`: duration policies, modifier types, stacking rules,
|
|
4
|
+
execution calculations, periodic effects, and conditional effects.
|
|
5
|
+
|
|
6
|
+
Source: `GameplayEffect.h` (UE5.3+, modular GE component architecture)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Duration Policies (`EGameplayEffectDurationType`)
|
|
11
|
+
|
|
12
|
+
| Value | Behavior |
|
|
13
|
+
|-------|----------|
|
|
14
|
+
| `Instant` | Executes once, modifies base value permanently, never enters the active container |
|
|
15
|
+
| `HasDuration` | Active for a set time, then removed; modifies current value temporarily |
|
|
16
|
+
| `Infinite` | Active until `RemoveActiveGameplayEffect` is called; use for passive bonuses |
|
|
17
|
+
|
|
18
|
+
Instant effects call `PostGameplayEffectExecute` on the AttributeSet; duration/infinite effects
|
|
19
|
+
do not (they work through aggregators on the current value).
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Modifier Operations (`EGameplayModOp`)
|
|
24
|
+
|
|
25
|
+
The modifier equation is evaluated in this order across all active modifiers:
|
|
26
|
+
```
|
|
27
|
+
Final = ((BaseValue + AddBase) * MultiplyAdditive / DivideAdditive * MultiplyCompound) + AddFinal
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
| Op | Enum | Effect |
|
|
31
|
+
|----|------|--------|
|
|
32
|
+
| `Additive` | `EGameplayModOp::Additive` | Adds to the attribute (+10 hp) |
|
|
33
|
+
| `Multiplicative` | `EGameplayModOp::Multiplicative` | Multiplies (1.25x damage) |
|
|
34
|
+
| `Division` | `EGameplayModOp::Division` | Divides; applied as additive in denominator |
|
|
35
|
+
| `Override` | `EGameplayModOp::Override` | Replaces the attribute value entirely |
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Magnitude Calculation Types (`EGameplayEffectMagnitudeCalculation`)
|
|
40
|
+
|
|
41
|
+
### ScalableFloat (most common)
|
|
42
|
+
A constant or level-scaled float. Supply a `FScalableFloat` backed optionally by a CurveTable:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
Modifier: Health
|
|
46
|
+
Operation: Additive
|
|
47
|
+
Magnitude Type: ScalableFloat
|
|
48
|
+
Scalable Float Magnitude: -50.0 (or reference a CurveTable row for level scaling)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### AttributeBased
|
|
52
|
+
Derives magnitude from another attribute. Formula:
|
|
53
|
+
```
|
|
54
|
+
(Coefficient * (PreMultiplyAdditive + [Attribute Value])) + PostMultiplyAdditive
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
Magnitude Type: AttributeBased
|
|
59
|
+
Backing Attribute: SourceObject.AttackPower (capture from Source or Target)
|
|
60
|
+
Attribute Calculation Type: AttributeMagnitude (final evaluated value)
|
|
61
|
+
Coefficient: 1.0
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`EAttributeBasedFloatCalculationType` options:
|
|
65
|
+
- `AttributeMagnitude`: Final current value (includes active modifiers)
|
|
66
|
+
- `AttributeBaseValue`: Permanent base value only
|
|
67
|
+
- `AttributeBonusMagnitude`: Final - Base (modifier contribution only)
|
|
68
|
+
|
|
69
|
+
### CustomCalculationClass
|
|
70
|
+
Runs a `UGameplayModMagnitudeCalculation` subclass for arbitrary logic:
|
|
71
|
+
|
|
72
|
+
```cpp
|
|
73
|
+
UCLASS()
|
|
74
|
+
class UMyDamageMagnitudeCalc : public UGameplayModMagnitudeCalculation
|
|
75
|
+
{
|
|
76
|
+
GENERATED_BODY()
|
|
77
|
+
public:
|
|
78
|
+
UMyDamageMagnitudeCalc();
|
|
79
|
+
|
|
80
|
+
virtual float CalculateBaseMagnitude_Implementation(
|
|
81
|
+
const FGameplayEffectSpec& Spec) const override;
|
|
82
|
+
|
|
83
|
+
private:
|
|
84
|
+
// Declare captures in constructor
|
|
85
|
+
FGameplayEffectAttributeCaptureDefinition AttackPowerDef;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
UMyDamageMagnitudeCalc::UMyDamageMagnitudeCalc()
|
|
89
|
+
{
|
|
90
|
+
// Capture AttackPower from Source at execution time (not snapshot)
|
|
91
|
+
AttackPowerDef = FGameplayEffectAttributeCaptureDefinition(
|
|
92
|
+
UMyAttackSet::GetAttackPowerAttribute(),
|
|
93
|
+
EGameplayEffectAttributeCaptureSource::Source,
|
|
94
|
+
false /*bSnapshot*/);
|
|
95
|
+
RelevantAttributesToCapture.Add(AttackPowerDef);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
float UMyDamageMagnitudeCalc::CalculateBaseMagnitude_Implementation(
|
|
99
|
+
const FGameplayEffectSpec& Spec) const
|
|
100
|
+
{
|
|
101
|
+
FAggregatorEvaluateParameters EvalParams;
|
|
102
|
+
EvalParams.SourceTags = Spec.CapturedSourceTags.GetAggregatedTags();
|
|
103
|
+
EvalParams.TargetTags = Spec.CapturedTargetTags.GetAggregatedTags();
|
|
104
|
+
|
|
105
|
+
float AttackPower = 0.f;
|
|
106
|
+
GetCapturedAttributeMagnitude(AttackPowerDef, Spec, EvalParams, AttackPower);
|
|
107
|
+
return AttackPower * 1.5f; // Example: 150% of attack power
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### SetByCaller
|
|
112
|
+
The caller sets the magnitude at spec creation time using a tag as the key.
|
|
113
|
+
|
|
114
|
+
In the GE asset:
|
|
115
|
+
```
|
|
116
|
+
Magnitude Type: SetByCaller
|
|
117
|
+
DataTag: SetByCaller.Damage
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
In ability/code:
|
|
121
|
+
```cpp
|
|
122
|
+
FGameplayEffectSpecHandle SpecHandle = MakeOutgoingGameplayEffectSpec(DamageEffectClass, Level);
|
|
123
|
+
SpecHandle.Data->SetSetByCallerMagnitude(
|
|
124
|
+
FGameplayTag::RequestGameplayTag("SetByCaller.Damage"), 75.f);
|
|
125
|
+
ApplyGameplayEffectSpecToTarget(Handle, ActorInfo, ActivationInfo, SpecHandle, TargetASC);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Execution Calculations (`UGameplayEffectExecutionCalculation`)
|
|
131
|
+
|
|
132
|
+
Executions are for complex damage formulas that modify multiple attributes at once.
|
|
133
|
+
They run on instant GEs and fire `PostGameplayEffectExecute` on the AttributeSet.
|
|
134
|
+
|
|
135
|
+
```cpp
|
|
136
|
+
UCLASS()
|
|
137
|
+
class UMyDamageExecution : public UGameplayEffectExecutionCalculation
|
|
138
|
+
{
|
|
139
|
+
GENERATED_BODY()
|
|
140
|
+
public:
|
|
141
|
+
UMyDamageExecution();
|
|
142
|
+
|
|
143
|
+
virtual void Execute_Implementation(
|
|
144
|
+
const FGameplayEffectCustomExecutionParameters& ExecutionParams,
|
|
145
|
+
FGameplayEffectCustomExecutionOutput& OutExecutionOutput) const override;
|
|
146
|
+
|
|
147
|
+
private:
|
|
148
|
+
FGameplayEffectAttributeCaptureDefinition AttackPowerDef;
|
|
149
|
+
FGameplayEffectAttributeCaptureDefinition ArmorDef;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
UMyDamageExecution::UMyDamageExecution()
|
|
153
|
+
{
|
|
154
|
+
AttackPowerDef = FGameplayEffectAttributeCaptureDefinition(
|
|
155
|
+
UMyAttackSet::GetAttackPowerAttribute(),
|
|
156
|
+
EGameplayEffectAttributeCaptureSource::Source,
|
|
157
|
+
true /*bSnapshot*/);
|
|
158
|
+
|
|
159
|
+
ArmorDef = FGameplayEffectAttributeCaptureDefinition(
|
|
160
|
+
UMyDefenseSet::GetArmorAttribute(),
|
|
161
|
+
EGameplayEffectAttributeCaptureSource::Target,
|
|
162
|
+
false);
|
|
163
|
+
|
|
164
|
+
RelevantAttributesToCapture.Add(AttackPowerDef);
|
|
165
|
+
RelevantAttributesToCapture.Add(ArmorDef);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
void UMyDamageExecution::Execute_Implementation(
|
|
169
|
+
const FGameplayEffectCustomExecutionParameters& ExecutionParams,
|
|
170
|
+
FGameplayEffectCustomExecutionOutput& OutExecutionOutput) const
|
|
171
|
+
{
|
|
172
|
+
const FGameplayEffectSpec& Spec = ExecutionParams.GetOwningSpec();
|
|
173
|
+
|
|
174
|
+
FAggregatorEvaluateParameters EvalParams;
|
|
175
|
+
EvalParams.SourceTags = Spec.CapturedSourceTags.GetAggregatedTags();
|
|
176
|
+
EvalParams.TargetTags = Spec.CapturedTargetTags.GetAggregatedTags();
|
|
177
|
+
|
|
178
|
+
float AttackPower = 0.f;
|
|
179
|
+
ExecutionParams.AttemptCalculateCapturedAttributeMagnitude(
|
|
180
|
+
AttackPowerDef, EvalParams, AttackPower);
|
|
181
|
+
|
|
182
|
+
float Armor = 0.f;
|
|
183
|
+
ExecutionParams.AttemptCalculateCapturedAttributeMagnitude(
|
|
184
|
+
ArmorDef, EvalParams, Armor);
|
|
185
|
+
|
|
186
|
+
// Example formula: damage = (attack * 2) - armor, min 1
|
|
187
|
+
float Damage = FMath::Max(1.f, (AttackPower * 2.f) - Armor);
|
|
188
|
+
|
|
189
|
+
// Output modifier: subtract from Health on target
|
|
190
|
+
OutExecutionOutput.AddOutputModifier(FGameplayModifierEvaluatedData(
|
|
191
|
+
UMyHealthSet::GetHealthAttribute(),
|
|
192
|
+
EGameplayModOp::Additive,
|
|
193
|
+
-Damage));
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
In the GE asset, add this class to `Executions` array (replaces individual Modifiers for complex
|
|
198
|
+
calculations).
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Stacking
|
|
203
|
+
|
|
204
|
+
### Stacking Type (`EGameplayEffectStackingType`)
|
|
205
|
+
|
|
206
|
+
| Value | Behavior |
|
|
207
|
+
|-------|----------|
|
|
208
|
+
| `None` | No stacking; each application is a separate active effect |
|
|
209
|
+
| `AggregateBySource` | One stack group per source ASC applying the effect |
|
|
210
|
+
| `AggregateByTarget` | One stack group regardless of source; all sources share one stack |
|
|
211
|
+
|
|
212
|
+
### Stack Limit
|
|
213
|
+
|
|
214
|
+
Set `StackLimitCount` in the GE asset. A value of 0 means unlimited.
|
|
215
|
+
|
|
216
|
+
### Duration Policy While Stacking (`EGameplayEffectStackingDurationPolicy`)
|
|
217
|
+
|
|
218
|
+
| Value | Behavior |
|
|
219
|
+
|-------|----------|
|
|
220
|
+
| `RefreshOnSuccessfulApplication` | Duration resets on each successful stack add |
|
|
221
|
+
| `NeverRefresh` | Duration is set at first application, never extended |
|
|
222
|
+
| `ExtendDuration` | Each new stack adds the spec's full duration to remaining time |
|
|
223
|
+
|
|
224
|
+
### Expiration Policy (`EGameplayEffectStackingExpirationPolicy`)
|
|
225
|
+
|
|
226
|
+
| Value | Behavior |
|
|
227
|
+
|-------|----------|
|
|
228
|
+
| `ClearEntireStack` | All stacks removed when the effect expires |
|
|
229
|
+
| `RemoveSingleStackAndRefreshDuration` | Decrement by 1 and restart duration |
|
|
230
|
+
| `RefreshDuration` | Duration refreshes (effectively infinite until manually removed) |
|
|
231
|
+
|
|
232
|
+
### Reading Stack Count at Runtime
|
|
233
|
+
|
|
234
|
+
```cpp
|
|
235
|
+
// By active handle:
|
|
236
|
+
int32 StackCount = AbilitySystemComponent->GetCurrentStackCount(ActiveHandle);
|
|
237
|
+
|
|
238
|
+
// By query:
|
|
239
|
+
FGameplayEffectQuery Query = FGameplayEffectQuery::MakeQuery_MatchAllOwningTags(
|
|
240
|
+
FGameplayTagContainer(PoisonEffectTag));
|
|
241
|
+
int32 TotalStacks = AbilitySystemComponent->GetAggregatedStackCount(Query);
|
|
242
|
+
|
|
243
|
+
// Update SetByCaller on active stacking effect:
|
|
244
|
+
AbilitySystemComponent->UpdateActiveGameplayEffectSetByCallerMagnitude(
|
|
245
|
+
ActiveHandle,
|
|
246
|
+
FGameplayTag::RequestGameplayTag("SetByCaller.StackDamage"),
|
|
247
|
+
NewDamageValue);
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Periodic Effects (Damage Over Time)
|
|
253
|
+
|
|
254
|
+
Set in the GE asset:
|
|
255
|
+
```
|
|
256
|
+
Duration Policy: HasDuration
|
|
257
|
+
Duration Magnitude: 10.0 (total duration in seconds)
|
|
258
|
+
Period: 1.0 (execute every 1 second)
|
|
259
|
+
Execute Periodic Effect on Application: true/false
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
`EGameplayEffectStackingPeriodPolicy` controls what happens to the period timer on stack add:
|
|
263
|
+
- `ResetOnSuccessfulApplication`: Timer resets to full period on each stack
|
|
264
|
+
- `NeverReset`: Timer continues uninterrupted
|
|
265
|
+
|
|
266
|
+
Period callbacks on the ASC:
|
|
267
|
+
```cpp
|
|
268
|
+
// Called on server when a periodic GE executes on self:
|
|
269
|
+
AbilitySystemComponent->OnPeriodicGameplayEffectExecuteDelegateOnSelf.AddUObject(
|
|
270
|
+
this, &AMyCharacter::OnPeriodicEffectExecuted);
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Conditional Effects (`FConditionalGameplayEffect`)
|
|
276
|
+
|
|
277
|
+
Apply secondary effects only when a primary execution succeeds:
|
|
278
|
+
|
|
279
|
+
```cpp
|
|
280
|
+
// In GE asset, set up Executions[0].ConditionalGameplayEffects:
|
|
281
|
+
FConditionalGameplayEffect ConditionalEntry;
|
|
282
|
+
ConditionalEntry.EffectClass = UMyBurnEffect::StaticClass();
|
|
283
|
+
ConditionalEntry.RequiredSourceTags.AddTag(
|
|
284
|
+
FGameplayTag::RequestGameplayTag("Ability.FireType")); // Source must have this tag
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
The conditional effect is applied to the same target as the parent execution.
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## Immunity
|
|
292
|
+
|
|
293
|
+
Block specific GEs from applying using the `UImmunityGameplayEffectComponent` (UE 5.3+).
|
|
294
|
+
In the GE asset, add this component and configure its tag query to match incoming GE source tags.
|
|
295
|
+
|
|
296
|
+
`GrantedApplicationImmunityTags` (deprecated since UE 5.3) was the legacy property for this.
|
|
297
|
+
New code should use `UImmunityGameplayEffectComponent` in the GE component list instead.
|
|
298
|
+
|
|
299
|
+
When an ASC has this GE active, any incoming GE matching the immunity query is blocked.
|
|
300
|
+
The `OnImmunityBlockGameplayEffectDelegate` fires on the ASC when a block occurs:
|
|
301
|
+
|
|
302
|
+
```cpp
|
|
303
|
+
AbilitySystemComponent->OnImmunityBlockGameplayEffectDelegate.AddUObject(
|
|
304
|
+
this, &AMyCharacter::OnImmunityBlockGE);
|
|
305
|
+
|
|
306
|
+
void AMyCharacter::OnImmunityBlockGE(
|
|
307
|
+
const FGameplayEffectSpec& BlockedSpec,
|
|
308
|
+
const FActiveGameplayEffect* ImmunityEffect)
|
|
309
|
+
{
|
|
310
|
+
// Log or trigger "immune" visual feedback
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## Querying Active Effects
|
|
317
|
+
|
|
318
|
+
```cpp
|
|
319
|
+
// Get all active effect handles matching a query:
|
|
320
|
+
FGameplayEffectQuery Query;
|
|
321
|
+
Query.EffectTagQuery = FGameplayTagQuery::MakeQuery_MatchAnyTags(
|
|
322
|
+
FGameplayTagContainer(FGameplayTag::RequestGameplayTag("Effect.Type.Buff")));
|
|
323
|
+
|
|
324
|
+
TArray<FActiveGameplayEffectHandle> Handles =
|
|
325
|
+
AbilitySystemComponent->GetActiveEffects(Query);
|
|
326
|
+
|
|
327
|
+
// Get time remaining:
|
|
328
|
+
TArray<float> Remaining = AbilitySystemComponent->GetActiveEffectsTimeRemaining(Query);
|
|
329
|
+
|
|
330
|
+
// Remove all matching:
|
|
331
|
+
AbilitySystemComponent->RemoveActiveEffects(Query);
|
|
332
|
+
|
|
333
|
+
// Remove those with specific granted tags:
|
|
334
|
+
AbilitySystemComponent->RemoveActiveEffectsWithGrantedTags(
|
|
335
|
+
FGameplayTagContainer(FGameplayTag::RequestGameplayTag("Buff.Speed")));
|
|
336
|
+
|
|
337
|
+
// Remove those with specific applied source tags:
|
|
338
|
+
AbilitySystemComponent->RemoveActiveEffectsWithSourceTags(
|
|
339
|
+
FGameplayTagContainer(FGameplayTag::RequestGameplayTag("Effect.Poison")));
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## Effect Application Callbacks
|
|
345
|
+
|
|
346
|
+
```cpp
|
|
347
|
+
// Any GE applied to self (server-side):
|
|
348
|
+
AbilitySystemComponent->OnGameplayEffectAppliedDelegateToSelf.AddUObject(
|
|
349
|
+
this, &AMyCharacter::OnEffectApplied);
|
|
350
|
+
|
|
351
|
+
void AMyCharacter::OnEffectApplied(
|
|
352
|
+
UAbilitySystemComponent* Source,
|
|
353
|
+
const FGameplayEffectSpec& Spec,
|
|
354
|
+
FActiveGameplayEffectHandle Handle)
|
|
355
|
+
{
|
|
356
|
+
// React to any applied effect
|
|
357
|
+
// Use Spec.Def->DurationPolicy to determine if instant/duration/infinite
|
|
358
|
+
UE_LOG(LogTemp, Log, TEXT("Effect applied: %s"), *GetNameSafe(Spec.Def));
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Duration-based GE added (client + server):
|
|
362
|
+
AbilitySystemComponent->OnActiveGameplayEffectAddedDelegateToSelf.AddUObject(
|
|
363
|
+
this, &AMyCharacter::OnActiveEffectAdded);
|
|
364
|
+
|
|
365
|
+
// GE removed — subscribe per active effect handle after applying:
|
|
366
|
+
FOnActiveGameplayEffectRemoved_Info* RemovalDelegate =
|
|
367
|
+
AbilitySystemComponent->OnGameplayEffectRemoved_InfoDelegate(ActiveHandle);
|
|
368
|
+
if (RemovalDelegate)
|
|
369
|
+
{
|
|
370
|
+
RemovalDelegate->AddUObject(this, &AMyCharacter::OnEffectRemoved);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
void AMyCharacter::OnEffectRemoved(const FGameplayEffectRemovalInfo& RemovalInfo)
|
|
374
|
+
{
|
|
375
|
+
// RemovalInfo.ActiveEffect holds the effect that was removed
|
|
376
|
+
// RemovalInfo.bPrematureRemoval is true if removed before natural expiry
|
|
377
|
+
}
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
## UE5.3+ Modular GE Components
|
|
383
|
+
|
|
384
|
+
Since UE 5.3, `UGameplayEffect` uses `UGameplayEffectComponents` instead of monolithic
|
|
385
|
+
properties for many behaviors. Legacy properties still work (the system auto-upgrades via
|
|
386
|
+
`PostCDOCompiled`), but new GEs should prefer the component approach in the editor.
|
|
387
|
+
|
|
388
|
+
Key components include:
|
|
389
|
+
- `UAdditionalEffectsGameplayEffectComponent` — conditional and chained GEs
|
|
390
|
+
- `UBlockAbilityTagsGameplayEffectComponent` — block abilities while active
|
|
391
|
+
- `UTargetTagsGameplayEffectComponent` — grant tags to the target actor while active
|
|
392
|
+
- `UImmunityGameplayEffectComponent` — immunity to incoming GEs
|
|
393
|
+
- `UTargetTagRequirementsGameplayEffectComponent` — required/ignored tags on target for application/continuation
|
|
394
|
+
|
|
395
|
+
These replace what was previously set directly on `UGameplayEffect` properties. When
|
|
396
|
+
reading older code, map properties like `GrantedTags`, `InhibitionTags`, and
|
|
397
|
+
`ApplicationTagRequirements` to their respective component equivalents.
|