Site
WCGASAlly Module
UE 5.7+ · v1.0.4 · Wonderscape Creations

GAS Ally

The complete beginner-to-advanced documentation for the WCGASAlly module — Wonderscape Creations' deep RPG extension for Unreal Engine's Gameplay Ability System.

Unreal Engine 5.7+ GAS Extension Multiplayer Ready Blueprint Exposed AI Powered

🧬 What is GAS Ally?

GAS Ally (WCGASAlly) is the flagship RPG-depth module of the Wonderscape Creations plugin framework. It sits on top of Unreal Engine's Gameplay Ability System (GAS) and the WCGASCore attribute layer to deliver a complete, production-ready RPG character simulation system.

Where vanilla GAS gives you raw tools — Attributes, Abilities, and Effects — GAS Ally gives you fully designed RPG systems built on those tools: dynamic leveling, multi-layer heritage (race/class/subclass), skill trees, status effect evolution chains, multi-layer resistance, squad AI, boss phases, world context reactions, and much more.

🧬

Heritage System

Race, class, subrace, and class blessings. Each Heritage Set shapes base attributes and unlocks passive gameplay effects.

📈

Dynamic Leveling

12 formula types for XP curves. Configurable thresholds, milestones, and level-up rewards all driven by data assets.

🌳

Skill Trees

Designer-authored skill tree presets with custom unlock requirements, point costs, and MMC-based stat bonuses.

💀

Status Effects

Status effect evolution chains, synergy combos, stacking rules, and per-tick processing — all data-driven.

🛡️

Resistance System

Four independent resistance layers: Damage Reduction, Absorption, Diminishing Returns, and Resilience — with immunity support.

🤖

AI Combat

Behavior Tree nodes, EQS contexts, StateTree tasks, squad coordination, multi-tier threat, and boss phase transitions.

🌍

World Context

Environment volumes that apply Gameplay Effects based on proximity — weather, biomes, day/night, temperature.

🎓

Ability Curriculum

Guided ability learning system with costs, prerequisites, save/load support, and Blueprint library integration.

ℹ️
Module Dependency: WCGASAlly depends on WCGASCore for its attribute pool and ability foundation. You do not need to use every other framework module — GAS Ally can be used with just the core GAS layer.

How GAS Ally Relates to Other Modules

L3 Integration
WCCombat WCInventory WCDynamicSociety WCUIFramework
L2 Features
WCGASAlly ← You Are Here WCInput WCInteraction WCAudioSuite
L1 Foundation
WCGASCore DynamicRPGWorlds (Core)

✅ Prerequisites

Before diving into GAS Ally, make sure your environment and knowledge base are properly prepared.

Engine & Tools

RequirementVersionNotes
Unreal Engine5.7.0+GAS Ally is built for UE 5.7+. No earlier versions supported.
PlatformWindows 64-bitMac, Linux, Android, and iOS are excluded in the plugin manifest.
Visual Studio2022Required for C++ compilation. Install the "Game development with C++" workload.
Project TypeC++ ProjectA Blueprint-only project must be converted before the plugin will compile.

Required Engine Plugins (Auto-Enabled)

WCGASAlly's .uplugin automatically enables these. You do not need to enable them manually:

PluginWhy GAS Ally Needs It
GameplayAbilitiesCore GAS foundation — attributes, effects, abilities, attribute sets.
DataValidationEditor-time asset validation runs on all Data Assets via WCGASAllyEditor.
StateTreeAI StateTree tasks and conditions used by the AI combat system.
GameplayStateTreeBridges GAS (Gameplay Tags, ASC queries) into StateTree logic.

Knowledge Prerequisites

GAS Ally is complex. The following knowledge will dramatically reduce your ramp-up time:

TopicImportanceWhere to Learn
Gameplay Ability System (GAS)Essentialtranek/GASDocumentation
Gameplay TagsEssentialUE Docs — Gameplay Tags
Gameplay EffectsEssentialUE Docs — Gameplay Effects
Data Assets (Primary/Secondary)EssentialUE Docs — Primary Data Assets
Modifier Magnitude Calculations (MMC)Importanttranek GASDocumentation — MMC section
Gameplay CuesImportantUE Docs — Gameplay Cues
Behavior Trees & EQSHelpful for AIUE Docs — Behavior Trees
StateTreeHelpful for AIUE Docs — StateTree
💡
Beginner Tip: You do NOT need to be a GAS expert to start using GAS Ally. The plugin's Data Assets and Blueprint-exposed APIs abstract away the complex GAS internals for most day-to-day work. However, when you need to extend the system in C++, GAS knowledge becomes essential.

🔧 Installation

GAS Ally ships as part of the Dynamic RPG Worlds plugin package. You install the whole plugin, then use whichever modules you need.

  1. Convert to C++ Project (if needed)

    Blueprint-only projects cannot compile the plugin. If your project has no Source/ folder:

    1. Open Unreal Editor
    2. Go to Tools → New C++ Class
    3. Choose any parent class (e.g., Actor) and click Create Class
    4. The editor will generate the Source/ folder and .sln file
  2. Place the Plugin

    Copy the entire DynamicRPGWorlds folder into your project's Plugins/ directory. Create the directory if it doesn't exist:

    YourProject/
    ├── Content/
    ├── Source/
    └── Plugins/
        └── DynamicRPGWorlds/        ← the whole plugin folder goes here
            ├── DynamicRPGWorlds.uplugin
            ├── Source/
            │   ├── WCGASAlly/       ← GAS Ally runtime module
            │   └── WCGASAllyEditor/ ← GAS Ally editor module
            └── Documentation/
  3. Enable in the Editor

    1. Open your project in Unreal Editor (it will offer to rebuild — click Yes)
    2. Go to Edit → Plugins
    3. Search for "Dynamic RPG Worlds"
    4. Toggle Enabled and click Restart Now
  4. Rebuild Project Files

    Right-click your .uproject file in Windows Explorer and choose "Generate Visual Studio project files" so the new modules appear in your solution.

  5. Compile

    Open the .sln in Visual Studio 2022. Select Development Editor | Win64 configuration and press Ctrl+Shift+B.

    ⚠️
    The first build compiles hundreds of files across all modules. Expect 5–15 minutes depending on your hardware. Subsequent builds are incremental and take seconds.
  6. Verify the GAS Ally Module

    After the Editor launches, verify:

    • Edit → Project Settings → scroll to the "WC GAS Ally" section — you should see it
    • Right-click in the Content Browser → Miscellaneous → Data Asset — search for WCGASAlly to see all GAS Ally Data Asset types available
    • Check the Output Log for LogWCGASAlly category messages at startup

🚀 Quick Start Guide

Follow this guide to build a working GAS Ally character from scratch — with heritage, leveling, a skill tree, and a status effect — in under one hour.

📋 What We'll Build

  1. A player character with a Heritage (race + class)
  2. A leveling system with XP and level-up rewards
  3. A skill tree with two unlockable nodes
  4. A "Burning" status effect that evolves into "Scorched" at 3 stacks
  5. A basic damage resistance layer

Step 1 — Add GAS Ally Components to Your Character

Open your player character Blueprint (parent: WCPlayerCharacter or any AWCCharacterBase descendant). In the Components panel, add the following components if not already present:

ComponentClass NamePurpose
LevelingUWCLevelingComponentTracks XP, current level, milestones
HeritageUWCHeritageComponentApplies race/class/subrace attribute modifications
Skill TreeUWCSkillTreeComponentManages skill point spending and node unlocking
Status EffectUWCStatusEffectComponentTracks active status effects, stacks, evolution
ResistanceUWCResistanceComponentManages DR, absorption, and resilience layers
Auto RegenUWCAutoRegenComponentDrives tick-based attribute regeneration
Ability CurriculumUWCAbilityCurriculumComponentManages learnable ability catalog and costs
ℹ️
Already Included: If your character inherits from WCPlayerCharacter provided by the framework's Core module, many of these components are already configured on the base class. Check the Components panel before adding duplicates.

Step 2 — Create a Heritage Set (Race + Class)

  1. Create a Race Definition

    In Content Browser: Right-click → Miscellaneous → Data Asset → WCHeritage_RaceDefinition. Name it DA_WC_Race_Human. Configure:

    • Display Name: "Human"
    • Base Attribute Modifiers: add a modifier for Health.Max (+50), Stamina.Max (+25)
    • Racial Blessings: leave empty for now (covered in Advanced section)
  2. Create a Class Definition

    Right-click → Data Asset → WCHeritage_ClassDefinition. Name it DA_WC_Class_Warrior. Configure:

    • Display Name: "Warrior"
    • Class Attribute Modifiers: PhysicalAttack (+20), Armor (+15)
  3. Create a Heritage Set

    Right-click → Data Asset → WCHeritageSet. Name it DA_WC_Heritage_HumanWarrior.

    • Set Race to DA_WC_Race_Human
    • Set Class to DA_WC_Class_Warrior
    • Leave Subrace empty for now
  4. Apply Heritage at BeginPlay

    On your character Blueprint's Event BeginPlay node, call the UWCHeritageComponent function: Apply Heritage Set, passing in DA_WC_Heritage_HumanWarrior.

Step 3 — Set Up Leveling

  1. Create Leveling Rules

    Right-click → Data Asset → WCLevelingRules. Name it DA_WC_LevelingRules_Default.

    • Formula Type: choose Exponential for a classic RPG curve
    • Base XP: 100
    • Exponent: 1.5 (each level requires 1.5× more XP)
    • Max Level: 50
    • Level-Up Rewards: add a row for every level — e.g., at Level 2: Grant 2 Skill Points
  2. Assign Rules to the Component

    On your character Blueprint, select the WCLevelingComponent. In the Details panel, set Leveling Rules to DA_WC_LevelingRules_Default.

  3. Test Granting XP

    In the Blueprint, wire a test Input Action (e.g., press G) to call Grant XP on the WCLevelingComponent with an amount of 150. Watch for level-up notifications in the Output Log.

Step 4 — Build a Skill Tree

  1. Create Skill Tree Data

    Right-click → Data Asset → WCSkillTreePreset. Name it DA_WC_SkillTree_WarriorBasic. Add nodes:

    • Node 0 — "Iron Skin": Cost 1 point, no prerequisites, grants +10 Armor via Gameplay Effect
    • Node 1 — "Battle Hardened": Cost 2 points, requires Node 0, grants +25 Health Max via Gameplay Effect
  2. Assign the Preset

    On your character Blueprint, select the WCSkillTreeComponent. Set Skill Tree Preset to DA_WC_SkillTree_WarriorBasic.

  3. Unlock a Node

    Call Try Unlock Node on the WCSkillTreeComponent, passing the Node ID and the character's ASC. The component checks prerequisites and skill point costs automatically.

Step 5 — Add a Status Effect (Burning → Scorched)

  1. Create the "Burning" Status Effect Definition

    Right-click → Data Asset → WCStatusEffectDefinition. Name it DA_WC_Status_Burning.

    • Effect Tag: WC.Status.Burning
    • Stacking: Aggregate, Max Stacks: 5
    • Duration: 8 seconds
    • Tick Interval: 1 second
    • Tick GE: a Gameplay Effect that deals 5 fire damage per tick
  2. Create the "Scorched" Status Effect

    Create a second WCStatusEffectDefinition named DA_WC_Status_Scorched with more severe fire damage (15 per tick) and 12 second duration.

  3. Create an Evolution Rule

    Right-click → Data Asset → WCStatusEvolutionRule. Configure:

    • Source Effect: DA_WC_Status_Burning
    • Evolves To: DA_WC_Status_Scorched
    • Trigger: Stack Count ≥ 3
  4. Apply the Status in Blueprint

    Call Apply Status Effect on the target character's WCStatusEffectComponent, passing DA_WC_Status_Burning. Each repeated call adds a stack. At 3 stacks, the evolution triggers automatically.

💡
Test with AWCDummy: Place an AWCDummy actor in your level. It has a pre-configured ASC you can apply status effects to, letting you test evolution and resistance without needing a full combat setup.

🏗️ Architecture Overview

GAS Ally is organized into interconnected systems, each with its own component, subsystem, data assets, and function library. Understanding this structure is essential before building anything complex.

System Organization

SystemComponentSubsystemData Asset(s)
HeritageUWCHeritageComponentUWCHeritageSubsystemWCHeritageSet, WCHeritage_RaceDefinition, WCHeritage_ClassDefinition, WCHeritage_SubraceDefinition
LevelingUWCLevelingComponentUWCLevelingSubsystemWCLevelingRules
Skill TreeUWCSkillTreeComponentWCSkillTreePreset
Status EffectsUWCStatusEffectComponentUWCStatusEffectSubsystemWCStatusEffectDefinition, WCStatusEvolutionRule, WCStatusSynergyRule
ResistanceUWCResistanceComponentUWCResistanceSubsystemWCResistanceData
Auto RegenUWCAutoRegenComponentUWCRegenSubsystem
CurriculumUWCAbilityCurriculumComponentWCAbilityCurriculumData
Ability LibraryWCAbilityBook, WCAbilityPage
FeatsUWCFeatComponentWCFeatPool, WCFeatMilestone
World ContextUWCWorldContextSubsystemWCWorldContextData, Volumes (AWCWorldContextVolume)
TransferUWCTransferSubsystemWCTransferTypes
DifficultyUWCDifficultySubsystemWCDifficultyTier
FactionWCFactionRelations, WCFactionAgent
AI CombatUWCCombatAIComponentUWCCombatAISubsystemWCSquadData, WCThreatData, WCBossPhaseData
OverflowUWCOverflowSubsystem

Data Flow: How a Character is Initialized

1. BeginPlay — Character spawns, ASC is initialized (on PlayerState for players, on Character for AI)
2. Attribute Initializer (UWCGASAttributeInitializer) — Pools and registers attributes from Definitions; sets base values
3. Heritage Component — Applies race + class + subrace modifier Gameplay Effects to the ASC
4. Leveling Component — Restores saved XP / level; re-applies level-up rewards if any
5. Skill Tree Component — Restores unlocked nodes from save data; re-applies their Gameplay Effects
6. Ability Curriculum — Grants abilities that were previously learned and saved
7. Resistance Component — Registers resistance data so damage calculations can query it
8. Auto Regen Component — Starts tick-based regen for registered attributes (Health, Mana, Stamina)
9. Character is Ready — World Context volumes and status effects may now apply

The Editor Module (WCGASAllyEditor)

The editor module provides quality-of-life tooling that is not present at runtime. It includes:

  • Asset Factories — Right-click → Data Asset menus for all GAS Ally asset types
  • Attribute Validator — Validates attribute definition assets at editor compile time
  • Property Customizations — Custom Details panels for complex data structures (resistance tables, evolution chains)
  • Gameplay Debug Category — Adds a WCGASAlly category to the Gameplay Debugger (` → 5) showing live attribute values, active status effects, and threat data

📊 Attribute System

GAS Ally uses the WCGASCore attribute pool as its foundation. Rather than hard-coding UAttributeSet subclasses with fixed properties (the vanilla GAS approach), WCGASCore provides a dynamic pool of 150 float attribute slots that are mapped at runtime to named definitions.

How Attributes Work in GAS Ally

  1. You create a WCGASAttributeDefinition Data Asset for each attribute (Health, Mana, Stamina, PhysicalAttack, etc.).
  2. You register each definition in Project Settings → WCGASCore → Attribute Definitions.
  3. At runtime, the UWCGASAttributeInitializer component reads the registry and assigns each definition to a pool slot (up to 150).
  4. Every GAS Ally system (damage calcs, regen, resistance, skill trees) references attributes by their Gameplay Tag name, not by C++ property pointers — so you never need to recompile to add a new attribute.

Attribute Definition Properties

PropertyTypeDescription
AttributeTagFGameplayTagUnique tag identifier, e.g. WC.Attribute.Health
DisplayNameFTextHuman-readable name shown in UI
BaseValuefloatDefault starting value
MinValuefloatHard minimum (usually 0)
MaxValuefloatHard maximum (usually driven by a MaxAttribute)
MaxAttributeTagFGameplayTagOptional — links this attribute's max to another attribute's current value
bSupportsRegenboolEnables auto-regen subsystem processing for this attribute
RegenRateTagFGameplayTagPoints to another attribute that stores the regen rate (e.g. WC.Attribute.HealthRegenRate)
bSaveableboolWhether current value is included in save data
CategoryFNameOptional grouping for UI (e.g. "Vitals", "Offense", "Defense")

The 12 Formula Types (Attribute Modifiers)

When other systems (Heritage, Skill Trees, Leveling rewards) apply modifications to attributes, they use one of 12 formula types:

FormulaBehaviorExample
FlatAddAdds a fixed number+50 Health
FlatMultiplyMultiplies by a fixed factor×1.2 Attack
PercentAddAdds a percentage of base+10% of base Max Health
PercentMultiplyMultiplies current by a percent×85% (nerfs the stat)
ClampClamps attribute between min and max valuesEnsure Armor stays 0–500
OverrideSets to a specific value, ignoring all other modsForce Speed = 0 (frozen)
LevelScaleScales by character level+5 × Level Armor
AttributeRefDerives value from another attributeSpellPower = 0.5 × Intelligence
CurveTableReads from a UCurveTable keyed on levelXP required per level from a curve
ConditionalApplies only when a tag condition is met+30 Attack when WC.Buff.Enrage is active
StackingScales with stack count of an active effectEach Bleed stack = +3 damage
CustomCalls a custom UWCGASMMCalc subclassComplex multi-stat formula in C++
ℹ️
All formula evaluation is handled by UWCGASMMCalc_AttributeMod, the framework's universal Modifier Magnitude Calculation class. You rarely need to create custom MMCs unless your formula is uniquely complex.

🔩 Key Components

Every GAS Ally system is delivered as an Actor Component. You add them to any character (player or AI) and they auto-register with their corresponding subsystem.

Component Quick Reference

Component ClassReplicates?Add toKey Events/Functions
UWCLevelingComponentYesCharacter or PlayerState GrantXP, OnLevelUp (delegate), GetCurrentLevel
UWCHeritageComponentYesCharacter ApplyHeritageSet, GetActiveRace, GetActiveClass
UWCSkillTreeComponentYesCharacter or PlayerState TryUnlockNode, GetAvailablePoints, IsNodeUnlocked
UWCStatusEffectComponentYesAny Actor with ASC ApplyStatusEffect, RemoveStatusEffect, GetActiveEffects
UWCResistanceComponentYesAny Actor with ASC RegisterResistanceData, QueryFinalDamage
UWCAutoRegenComponentNo (server only)Any Actor with ASC PauseRegen, ResumeRegen, SetRegenMultiplier
UWCAbilityCurriculumComponentYesCharacter or PlayerState LearnAbility, CanLearnAbility, GetCurriculumProgress
UWCFeatComponentYesCharacter or PlayerState CheckMilestone, GetEarnedFeats
UWCCombatAIComponentServer onlyAI Character SetCurrentTarget, GetSquadAgent, TransitionBossPhase
⚠️
Multiplayer Rule: Always add GAS Ally components on the server. Components that replicate will push state to clients automatically. Components marked "Server only" should not be queried directly on clients — use replicated properties or RPCs instead.

⚙️ Subsystems

Subsystems are long-lived game-wide or world-wide singletons that manage global state for each GAS Ally system. They are accessed via GetWorld()->GetSubsystem<U...Subsystem>() in C++ or via the Blueprint function libraries.

Subsystem ClassTypeResponsibilities
UWCRegenSubsystemWorldTick-based regen and degen processing for all registered characters
UWCAttributeModSubsystemWorldQueues and batches attribute modification events for performance
UWCResistanceSubsystemWorldCentralized resistance query cache; reduces per-frame GE queries
UWCStatusEffectSubsystemWorldGlobal registry of active status effects; drives tick and evolution logic
UWCLevelingSubsystemWorldCentralized XP event routing; handles multi-grant and milestone checks
UWCHeritageSubsystemWorldValidates heritage asset combinations; caches applied GEs per character
UWCEventsSubsystemWorldGlobal event bus for GAS Ally events (level up, evolution, feat earned, etc.)
UWCWorldContextSubsystemWorldManages active context volumes and applies/removes their GEs dynamically
UWCOverflowSubsystemWorldHandles attribute value overflow (excess HP → shield, excess Mana → stored)
UWCCombatAISubsystemWorldManages squad registrations, threat tables, and boss phase orchestration
UWCDifficultySubsystemGame InstancePersists difficulty tier across levels; applies global difficulty GE modifiers

Listening to Subsystem Events

The UWCEventsSubsystem is the recommended way to react to GAS Ally events in Blueprint. All major events are broadcast as delegates:

// C++ — bind to the events subsystem
if (UWCEventsSubsystem* Events = GetWorld()->GetSubsystem<UWCEventsSubsystem>())
{
    Events->OnCharacterLevelUp.AddDynamic(this, &ThisClass::HandleLevelUp);
    Events->OnStatusEffectEvolved.AddDynamic(this, &ThisClass::HandleEvolution);
    Events->OnFeatEarned.AddDynamic(this, &ThisClass::HandleFeat);
}

⚙️ Settings Reference

GAS Ally settings live under Edit → Project Settings → WC GAS Ally via the UWCGASAllySettings class. All settings are loaded once at startup and cached.

PropertyTypeDescription
DefaultDifficultyTierTSoftObjectPtr<WCDifficultyTier>Starting difficulty tier applied on new game
GlobalStatusEvolutionRulesTArray<...>Evolution rules applied globally regardless of which component applied the effect
GlobalSynergyRulesTArray<...>Synergy combos checked globally across all active status effects
RegenTickIntervalfloatHow often (seconds) the regen subsystem ticks. Default: 0.25
bEnableOverflowSystemboolToggle the overflow attribute system entirely
bEnableDebugLoggingboolEnables verbose LogWCGASAlly output
DefaultResistanceDataTSoftObjectPtr<WCResistanceData>Fallback resistance rules used if a character has no resistance component
ThreatDecayIntervalfloatHow often (seconds) the threat system decays threat values. Default: 5.0
ThreatDecayRatefloatFraction of threat lost per decay tick. Default: 0.1 (10%)
MaxSquadSizeint32Hard cap on squad member count. Default: 8
BossPhaseTransitionDelayfloatSeconds to wait after threshold hit before triggering boss phase. Default: 0.5

🧬 Heritage System

The Heritage System defines a character's biological and vocational identity. A Heritage Set is composed of up to four layers:

🧬

Race

Base biological traits. Affects vitals, natural resistances, and grants racial passive effects.

⚔️

Class

Vocational archetype. Affects combat stats, unlocks class-specific abilities, and defines role bonuses.

🔬

Subrace

Optional refinement of race. Adds deeper thematic attributes and modifies racial bonuses.

Blessings

Optional passive GES granted at character creation. Can be unlocked by game events or quests.

Heritage Data Assets

WCHeritage_RaceDefinition

PropertyDescription
RaceTagGameplay Tag for this race, e.g. WC.Heritage.Race.Human
DisplayNameLocalizable name shown in character creation UI
DescriptionLore text for the race
AttributeModifiersArray of FWCAttributeModifierData — stat boosts applied via GE on character init
GrantedGameplayEffectsPermanent GEs granted at init (e.g. a passive "Night Vision" GE for Elves)
GrantedAbilitiesAbility classes granted automatically (e.g. "Darkvision" ability for Dark Elves)
ValidSubracesArray of compatible WCHeritage_SubraceDefinition assets

WCHeritage_ClassDefinition

PropertyDescription
ClassTagGameplay Tag, e.g. WC.Heritage.Class.Warrior
AttributeModifiersCombat stat boosts (Attack, Defense, Speed, etc.)
GrantedAbilitiesClass-specific ability classes granted at init
DefaultSkillTreePresetSkill tree automatically assigned when this class is chosen
DefaultCurriculumDataAbility curriculum automatically assigned

WCHeritageSet

The Heritage Set is the top-level asset you apply to a character. It references all four layers and is the only asset the WCHeritageComponent needs:

// Apply a heritage set in Blueprint via the component function
UWCHeritageComponent* Heritage = Character->FindComponentByClass<UWCHeritageComponent>();
Heritage->ApplyHeritageSet(HumanWarriorHeritageSet);

Heritage Validation

The WCGASAllyEditor module validates Heritage assets at compile time. Common validation errors:

ErrorCauseFix
"Subrace not valid for Race"The selected Subrace is not in the Race's ValidSubraces listAdd the Subrace to the Race's ValidSubraces array, or choose a compatible subrace
"Missing RaceTag"Race definition has no RaceTag assignedAssign a unique Gameplay Tag to the Race asset
"Duplicate heritage tag"Two races or two classes share the same Gameplay TagEnsure every heritage definition has a unique tag

📈 Leveling System

The Leveling System provides a completely data-driven approach to character progression. XP formulas, thresholds, milestones, and rewards are all authored in Data Assets — no C++ required for most setups.

WCLevelingRules Data Asset

PropertyTypeDescription
FormulaTypeEWCLevelingFormulaWhich XP formula to use (see table below)
BaseXPfloatXP required at Level 1 → 2
ExponentfloatUsed by Exponential / Power formulas
LinearIncrementfloatAdded XP per level (for Linear formula)
XPCurveTableUCurveTableCustom XP curve when FormulaType = CurveTable
MaxLevelint32Cap on character level
LevelUpRewardsTMap<int32, FWCLevelReward>Per-level reward configuration (skill points, GEs, abilities)
MilestonesTArray<FWCLevelMilestone>Special events at key levels (e.g. unlock Subrace choice at Level 5)

XP Formula Types

FormulaEquationBest For
LinearXP(L) = BaseXP + (LinearIncrement × L)Consistent, flat progression (casual games)
ExponentialXP(L) = BaseXP × Exponent^LClassic RPG steep late-game curve
PowerXP(L) = BaseXP × L^ExponentModerate curve that scales with level
PolynomialXP(L) = BaseXP × L² × ExponentQuadratic — mild early, steep late
CurveTableXP(L) = CurveTable.Eval(L)Full designer control per level
CustomCalls a subclassed UWCLevelingCustomFormulaComplex or runtime-dynamic formulas in C++

Level-Up Rewards

The LevelUpRewards TMap lets you specify exactly what happens at each level-up. Each FWCLevelReward struct contains:

  • SkillPointsGranted — How many skill points are added to the Skill Tree pool
  • AbilitiesToGrant — Array of ability classes to grant via the ASC
  • GameplayEffectsToApply — GEs applied at level-up (stat boosts, permanent buffs)
  • MilestoneTag — Optional tag broadcast on the events subsystem at this level

Using the Leveling Component

// Blueprint callable functions on UWCLevelingComponent:

// Grant XP (triggers level-up if threshold reached)
LevelingComp->GrantXP(500.0f);

// Get current level
int32 Level = LevelingComp->GetCurrentLevel();

// Get XP progress toward next level (0.0 - 1.0)
float Progress = LevelingComp->GetLevelProgress();

// Force set level (bypasses XP, used for save-game restore)
LevelingComp->SetLevel(10, /* bApplyRewards */ false);
ℹ️
Multiplayer Note: GrantXP must be called on the server. Level-up and reward processing happens server-side and replicates the new level/XP values to clients. Bind to the OnLevelUp multicast delegate for client-side effects (UI updates, VFX).

🌳 Skill Trees

The Skill Tree system is a graph-based progression system where characters spend earned skill points to unlock nodes that permanently enhance their capabilities.

WCSkillTreePreset Data Asset

A Skill Tree Preset defines the entire tree for a character archetype. Properties:

PropertyDescription
TreeTagUnique Gameplay Tag for this tree, e.g. WC.SkillTree.Warrior
DisplayNameName shown in UI
NodesArray of FWCSkillTreeNode structs defining all nodes

Skill Tree Node Properties (FWCSkillTreeNode)

PropertyDescription
NodeIDUnique integer ID within the tree
DisplayNameNode name shown in UI
DescriptionWhat this node does (for tooltips)
PointCostSkill points required to unlock
PrerequisiteNodeIDsArray of NodeIDs that must be unlocked first
GameplayEffectsToApplyGEs permanently applied when unlocked
AbilitiesToGrantAbilities granted when unlocked
UnlockRequirementOptional custom C++ UWCSkillTreeUnlockRequirement class for special gates
UIGridPositionFVector2D position for visual layout in the UI grid

MMC-Based Bonuses

Skill tree nodes that grant attribute bonuses use the GAS Modifier Magnitude Calculation system. The recommended pattern is to create a Gameplay Effect with a Modifier that uses an MMC_WCSkillTree_* class — these are pre-built MMCs in the framework that evaluate bonuses based on how many nodes in a category are unlocked:

// Example: A node that grants +5 Strength per Warrior-category node unlocked
// GE Modifier: Attribute = WC.Attribute.Strength
// Magnitude Calculation: MMC_WCSkillTree_CategoryCount
// Coefficient: 5.0
// Category Tag: WC.SkillTree.Category.Warrior

Custom Unlock Requirements Advanced

For complex unlock conditions (e.g. "Unlock only if player has completed a quest tag"), create a C++ class inheriting UWCSkillTreeUnlockRequirement and override:

UCLASS()
class UMyCustomUnlock : public UWCSkillTreeUnlockRequirement
{
    GENERATED_BODY()
public:
    virtual bool CanUnlock(const UWCSkillTreeComponent* TreeComp,
                           const UAbilitySystemComponent* ASC,
                           const FWCSkillTreeNode& Node) const override
    {
        // Your custom logic here
        return ASC->HasMatchingGameplayTag(FGameplayTag::RequestGameplayTag("WC.Quest.Completed.HunterTrial"));
    }
};

🎓 Ability Curriculum

The Ability Curriculum is a guided learning system for abilities. Instead of abilities being granted automatically (as with Heritage or Leveling), the Curriculum lets designers define a catalog of learnable abilities with costs and prerequisites — and players actively choose what to learn.

WCAbilityCurriculumData

PropertyDescription
CurriculumTagUnique tag for this curriculum, e.g. WC.Curriculum.Warrior
LearnableAbilitiesArray of FWCCurriculumEntry — each entry is one ability and its cost/prerequisite

Curriculum Entry (FWCCurriculumEntry)

PropertyDescription
AbilityClassThe Gameplay Ability class to learn
DisplayNameName shown in the ability selection UI
DescriptionTooltip / description text
CurrencyCostAmount of in-game currency required
SkillPointCostSkill points required (shared pool with Skill Tree)
RequiredLevelMinimum character level to learn
PrerequisiteAbilitiesArray of ability classes that must be learned first
RequiredTagsGameplay Tag Container — character must have ALL tags to learn this ability

Learning an Ability in Blueprint

  1. Check if Learnable

    Call CanLearnAbility(AbilityClass) on the UWCAbilityCurriculumComponent. Returns a struct with: bCanLearn, FailureReason (for UI feedback).

  2. Spend Resources and Learn

    Call LearnAbility(AbilityClass) on the server. The component deducts costs, grants the ability via the ASC, and saves the learned state.

  3. Listen for the Callback

    Bind to OnAbilityLearned delegate on the component or listen via the UWCEventsSubsystem.

📚 Ability Library

The Ability Library provides a hierarchical catalog system for organizing abilities — Books contain Pages, and Pages contain Ability Definitions. This gives designers a structured way to author and navigate large ability sets.

Asset TypeAnalogyContains
WCAbilityBookA spellbook tomeMultiple WCAbilityPage assets
WCAbilityPageA chapter in the tomeMultiple WCAbilityDefinition references
WCAbilityDefinitionA single spell/ability entryAbility class, metadata, requirements, icon

The Ability Library is primarily a data organization and query tool. You can ask it: "Give me all Fire magic abilities available to a Level 10 Mage" and it returns the filtered list. UI systems then present the results to the player.

// Blueprint API example:
// Get all abilities in a book that the character can use
TArray<FWCAbilityDefinition> Available = 
    UWCGASAbilityLibFuncLib::QueryAbilityBook(FireMagicBook, Character->GetASC());

🏆 Feats System

Feats are achievement-like milestones that characters earn through gameplay events. They are tracked by the UWCFeatComponent and trigger gameplay rewards when milestones are reached.

WCFeatPool

A collection of trackable feat counters. Each feat in the pool has:

PropertyDescription
FeatTagUnique tag, e.g. WC.Feat.EnemiesKilled
DisplayNameUI name, e.g. "Kills"
IncrementEventsGameplay Tags that, when fired at the ASC, automatically increment this counter

WCFeatMilestone

Milestones define rewards at specific counter thresholds:

PropertyDescription
FeatTagWhich feat counter this milestone watches
ThresholdCounter value that triggers this milestone
MilestoneTagBroadcast tag when milestone triggers
RewardGEGameplay Effect applied as reward (permanent stat boost, new ability, etc.)
bOneTimeOnlyIf true, only triggers once even if counter passes threshold again

Auto-Tracking via Gameplay Tags

The most powerful feature of Feats: they can auto-increment using existing Gameplay Event Tags. If you set IncrementEvents to include WC.Event.EnemyKilled, then every time that tag is sent to the ASC (e.g. by a damage execution), the feat counter goes up — no extra Blueprint wiring needed.

// Send a feat increment event from C++ or Blueprint
FGameplayEventData Payload;
UAbilitySystemBlueprintLibrary::SendGameplayEventToActor(
    Character, 
    FGameplayTag::RequestGameplayTag("WC.Event.EnemyKilled"),
    Payload
);

💀 Status Effects

GAS Ally's Status Effect system extends standard Gameplay Effects with stacking logic, custom tick behavior, evolution chains, and synergy combos. It is one of the most powerful and configurable systems in the plugin.

WCStatusEffectDefinition

PropertyDescription
EffectTagUnique tag, e.g. WC.Status.Burning
DisplayNameUI name
IconTexture2D icon for status bar UI
StackingPolicyHow stacks are counted: Aggregate, Replace, Unique
MaxStacksMaximum number of stacks allowed (1 = non-stacking)
DurationSecondsHow long the effect lasts. 0 = infinite (until removed)
bRefreshOnStackIf true, adding a stack resets the duration timer
TickIntervalSecondsHow often the Tick GE is applied. 0 = no tick
TickGameplayEffectGE applied each tick (damage, heal, drain, etc.)
OnApplyGameplayEffectGE applied once when first applied
OnRemoveGameplayEffectGE applied once when removed (e.g. reverse a stat debuff)
EvolutionRulesInline list of evolution conditions — see Status Evolution section
TagsToAddOnApplyGameplay Tags added to the target's tag container while active
TagsToBlockWhileActiveGameplay Tags that cannot be applied while this effect is active

Stacking Policies

PolicyBehavior
AggregateEach application adds a stack. All stacks share one timer (refreshable). Tick GE scales with stack count.
ReplaceEach new application replaces the previous entirely, resetting timer and stack count to 1.
UniqueApplying while already active does nothing. Only one instance allowed, no stacks.

Applying and Removing Status Effects

// Blueprint callable via UWCStatusEffectComponent:

// Apply a status effect (adds a stack if already present)
StatusEffectComp->ApplyStatusEffect(DA_WC_Status_Burning, Instigator);

// Remove all stacks of a specific status
StatusEffectComp->RemoveStatusEffect(DA_WC_Status_Burning);

// Remove one stack
StatusEffectComp->RemoveStatusEffectStack(DA_WC_Status_Burning, 1);

// Check if a status is active
bool bIsBurning = StatusEffectComp->IsStatusEffectActive(FGameplayTag("WC.Status.Burning"));

🔥 Status Effect Evolution

Evolution allows a status effect to automatically transform into a more powerful variant when certain conditions are met. This enables deep combat interaction design — e.g., Wet + Lightning = Electrified, or 3× Burning → Scorched.

WCStatusEvolutionRule

PropertyDescription
SourceEffectTagThe status effect that triggers the evolution
EvolvesToDefinitionThe WCStatusEffectDefinition to replace the source with
TriggerConditionWhat causes evolution: StackThreshold, DurationThreshold, TagPresent, HealthThreshold
StackThresholdStack count that triggers (used with StackThreshold condition)
DurationRemainingSecondsTriggers when this many seconds remain (used with DurationThreshold)
RequiredTagTag that must be present on target (used with TagPresent)
HealthPercentThresholdTarget health % at or below which evolution triggers (0.0–1.0)
bConsumeSourceIf true, the source status is removed when evolving (default: true)
bTransferStacksIf true, remaining stacks are transferred to the evolved effect

Evolution Flow

Event: Stack added / Tick occurs / Tag gained on target
WCStatusEffectSubsystem checks all Evolution Rules for any active effect
Condition Evaluated: Is StackCount ≥ Threshold? Is Tag present? Is Health ≤ threshold?
If condition met: Source effect removed (if bConsumeSource), Evolved effect applied
OnStatusEffectEvolved broadcast on UWCEventsSubsystem (bind for VFX/SFX/UI)
💡
You can chain evolutions. Burning → Scorched → Cindering by creating two evolution rules. GAS Ally processes them sequentially within the same tick if conditions are already met.

⚡ Status Synergy

Synergy goes beyond evolution — it triggers effects when two or more different status effects are active simultaneously on the same target. This creates emergent elemental interaction systems.

WCStatusSynergyRule

PropertyDescription
RequiredStatusTagsAll of these status tags must be active simultaneously to trigger the synergy
SynergyTagGameplay Tag broadcast as a Gameplay Event when synergy triggers
SynergyEffectOptional GE applied immediately when synergy fires (e.g. a burst of damage)
NewStatusToApplyOptional new status effect applied as a result of the synergy
bConsumeInputEffectsIf true, all RequiredStatusTags are removed when synergy fires
CooldownSecondsHow long before this synergy can trigger again on the same target
PriorityHigher priority synergies are evaluated first when multiple could fire simultaneously

Example: Wet + Burning = Explosion

// Synergy Rule Data Asset: DA_WC_Synergy_WetBurning
// RequiredStatusTags: [WC.Status.Wet, WC.Status.Burning]
// SynergyEffect: DA_GE_SteamExplosion (heavy AoE damage)
// NewStatusToApply: DA_WC_Status_Steamed (vision-impairing steam cloud)
// bConsumeInputEffects: true   (removes Wet and Burning)
// CooldownSeconds: 10.0
⚠️
Register all Synergy Rules in Project Settings → WC GAS Ally → Global Synergy Rules so the subsystem checks them globally. Per-character synergy rules can also be added directly to a WCStatusEffectDefinition's inline array, but global rules are the recommended approach for elemental interactions.

🛡️ Resistance System

GAS Ally provides four independent resistance layers, each implemented as a Gameplay Effect Component. They are evaluated in order during damage calculation and can be stacked, overridden, or diminished.

The Four Resistance Layers

🛡️

Damage Reduction (DR)

Flat point reduction applied before percentage calculations. Example: 50 DR reduces 100 damage to 50.

💧

Absorption

Percentage of damage absorbed after DR. Example: 20% absorption on 50 damage = 40 final damage.

📉

Diminishing Returns (DR²)

Prevents stacking resistance to trivialize combat. A DR² component caps effective resistance using a configured curve.

💪

Resilience

Post-absorption resilience factor — how quickly the character recovers from high damage spikes. Applied as a multiplier on the damage received this frame.

Resistance Data Asset (WCResistanceData)

PropertyDescription
DamageTypeTagWhich damage type this data applies to (e.g. WC.DamageType.Fire). Use WC.DamageType.Any for global resistance.
FlatReductionFlat DR amount subtracted from incoming damage
AbsorptionPercent0.0–1.0 percentage of post-DR damage absorbed
DiminishingCurveCurveFloat mapping total absorption % to effective absorption % (to implement DR²)
ResilienceFactorMultiplier on final damage received. 1.0 = no effect. 0.8 = 20% effective reduction.

Damage Calculation Order

Raw Damage — from the damage Gameplay Effect magnitude
Step 1 — Flat DR: FinalDmg = RawDmg - FlatReduction (clamped to 0)
Step 2 — Absorption: FinalDmg = FinalDmg × (1.0 - EffectiveAbsorption)
Step 3 — Diminishing Returns: EffectiveAbsorption capped by DiminishingCurve
Step 4 — Resilience: FinalDmg = FinalDmg × ResilienceFactor
Final Damage applied to Health attribute

Per-Damage-Type vs. Global Resistance

You can register multiple WCResistanceData assets with different DamageTypeTag values on the same character. When damage comes in, the system queries:

  1. Exact type match (e.g. WC.DamageType.Fire)
  2. Parent tag match (e.g. WC.DamageType.Elemental if Fire has no specific entry)
  3. Global fallback (WC.DamageType.Any)

All matching entries are combined — so a character can have base physical resistance AND bonus fire resistance from a Heritage effect simultaneously.

🚫 Immunity System

The Immunity GE Component (UWCImmunityGEComponent) is a Gameplay Effect Component that, when active on a character's ASC, blocks specific damage types or status effects entirely.

Creating an Immunity Effect

  1. Create a Gameplay Effect

    Create a new Gameplay Effect of type Infinite (since immunity usually needs to stay active).

  2. Add the Immunity Component

    In the GE's Gameplay Effect Components array, add WCImmunityGEComponent.

  3. Configure Tags to Block

    In the component's properties:

    • DamageTypesToBlock: Tag container of damage types that are completely nullified
    • StatusEffectsToBlock: Tag container of status effect tags that cannot be applied
    • bBlockAll: Set true for complete damage immunity (boss phase invincibility, cutscene, etc.)
  4. Apply the GE

    Apply this GE to the character's ASC like any Gameplay Effect. Remove it to end immunity.

🚨
Performance Warning: Do not apply Immunity GEs with very short durations on many actors every frame. The system caches immunity state, but constant apply/remove cycles bypass the cache. For toggling immunity frequently, use the WC.Status.Immune Gameplay Tag with TagsToBlockWhileActive on a Status Effect definition instead.

💚 Regen & Degeneration

The Auto-Regen system ticks at a configurable interval and applies regeneration or degeneration to any attribute that has bSupportsRegen = true in its definition and a configured regen-rate attribute.

How Regen Works

  1. The UWCRegenSubsystem ticks every RegenTickInterval seconds (default: 0.25s).
  2. For each registered character, it queries all attributes with bSupportsRegen = true.
  3. It reads the current value of the linked RegenRateTag attribute.
  4. It applies a small GE that adds RegenRate × TickInterval to the attribute.
  5. Degeneration works identically — a negative regen rate causes the attribute to decrease over time.

Regen MMCs

For more complex regen behavior (e.g. regen that scales with out-of-combat duration), GAS Ally provides pre-built MMCs:

MMC ClassBehavior
UWCGASMMCalc_PercentRegenRegenerates a percentage of max attribute per tick
UWCGASMMCalc_DegenerationApplies degeneration (negative regen) scaled by a tag condition
UWCGASMMCalc_AttributeModUniversal modifier calc (see Attribute System section)

Pausing and Resuming Regen

The UWCAutoRegenComponent exposes control functions for gameplay scenarios (stunned characters shouldn't regen mana, combat zones stop health regen, etc.):

// Pause all regen on this character
AutoRegenComp->PauseRegen();

// Resume with a multiplier (0.5 = half regen rate, useful for out-of-combat bonus)
AutoRegenComp->ResumeRegen(/* Multiplier */ 2.0f);

// Pause only specific attribute
AutoRegenComp->PauseAttributeRegen(FGameplayTag::RequestGameplayTag("WC.Attribute.Mana"));

⚔️ Damage & Healing Calculations

GAS Ally provides a rich set of Execution Calculations and helper libraries for all damage and healing processing.

Damage Execution Calculation

All combat damage flows through the GAS Execution Calculation system. GAS Ally's damage calc (UWCGASExecCalc_Damage) performs the following pipeline:

Capture: Read attacker's relevant offensive attributes (PhysicalAttack, SpellPower, CritChance, etc.)
Capture: Read target's relevant defensive attributes (Armor, MagicDefense, Evasion, etc.)
Base Damage: Apply attacker formula (e.g. PhysicalAttack × WeaponMultiplier - Armor)
Critical Hit: Roll CritChance; if success, multiply by CritDamageMultiplier
Resistance Pipeline: DR → Absorption → Diminishing Returns → Resilience (see Resistance section)
Apply: Set WC.Attribute.Health = Health - FinalDamage via Output Modifier
Events: Fire WC.Event.DamageTaken on target ASC; Gameplay Cue for VFX/SFX

Damage Calculation Library (UWCDamageCalcLibrary)

Blueprint-callable helper functions for querying and manually computing damage values:

FunctionDescription
CalculatePhysicalDamageCompute final physical damage between attacker and defender without applying it
CalculateMagicalDamageSame for magical damage (uses SpellPower, MagicDefense)
GetEffectiveDamageAfterResistanceRun only the resistance pipeline on a raw damage value
WillCriticalEvaluate crit chance roll (for ability prediction/preview)

Healing Execution Calculation

Healing uses UWCGASExecCalc_Healing. It captures the healer's HealingPower attribute, applies any healing bonuses (buffs via GE), and clamps the result to the target's MaxHealth. Overheal (excess healing) routes to the Overflow System if configured.

🤖 AI Systems Overview

GAS Ally ships a complete AI combat framework that integrates tightly with GAS. The AI system is not just about movement — it is a full tactical simulation layer including threat management, squad coordination, and boss phase scripting.

AI Architecture Layers

🌳

Behavior Trees

Custom BT Tasks, Decorators, and Services that query GAS state, manage threat, and coordinate with squads.

🗺️

EQS Integration

Custom EQS Contexts, Tests, and Generators that let AI queries understand GAS concepts like line of sight, threat range, and ally positions.

🔄

StateTree

StateTree Tasks and Conditions for high-level AI state management — patrol, combat, retreat, boss phases.

👥

Squad System

Groups of AI actors that share threat information, coordinate attacks, and divide roles (tank, flanker, ranged).

🎯

Threat System

Multi-tier threat tables that determine target priority. Threat decays over time and is modified by actions.

👑

Boss Phases

Health-threshold-based phase transitions that change AI behavior, abilities, and stats dramatically.

The Combat AI Component

UWCCombatAIComponent is the hub that connects all AI systems. Add it to any AI character class:

PropertyDescription
SquadDataReference to WCSquadData asset defining this AI's squad configuration
ThreatDataReference to WCThreatData asset defining threat modifiers and decay
BossPhaseDataReference to WCBossPhaseData asset (leave null for non-bosses)
CombatRangeMax distance at which this AI engages targets
PreferredCombatTagsTags for preferred combat style (Melee, Ranged, Support) — used by squad role assignment

🌳 Behavior Tree Nodes

GAS Ally provides a full library of custom Behavior Tree nodes in all three categories (Tasks, Decorators, Services) that understand the GAS Ally world.

Tasks

Task NodeDescription
BTTask_WC_UseGASAbilityActivate a Gameplay Ability by tag, ability class, or ability handle. Handles prediction keys for multiplayer.
BTTask_WC_ApplyStatusEffectApply a Status Effect Definition to a target actor (from BB key)
BTTask_WC_UpdateThreatManually modify threat values in the threat table (e.g. boost threat on the character that just healed an ally)
BTTask_WC_CallSquadActionBroadcast a squad action tag to all squad members (e.g. "FlankLeft", "FocusFire")
BTTask_WC_TransitionBossPhaseTrigger a boss phase transition manually from within a BT
BTTask_WC_SetCombatTargetSet the current combat target on the Combat AI Component and update threat
BTTask_WC_SendGameplayEventSend a Gameplay Event Tag to any actor's ASC from within a BT
BTTask_WC_WaitAbilityCooldownWait until a specific ability (by tag) is no longer on cooldown

Decorators

Decorator NodeDescription
BTDecorator_WC_HasGASTagSucceeds if the specified actor has (or does not have) a Gameplay Tag
BTDecorator_WC_AttributeThresholdSucceeds when an attribute value is above/below a threshold
BTDecorator_WC_IsStatusEffectActiveSucceeds if a specific status effect tag is active on the target
BTDecorator_WC_IsThreatLeaderSucceeds if this AI is the highest-threat target for its squad lead
BTDecorator_WC_AbilityReadySucceeds if a specific ability is not on cooldown
BTDecorator_WC_IsInBossPhaseSucceeds if this boss AI is currently in a specific phase number

Services

Service NodeDescription
BTService_WC_UpdateThreatTargetPeriodically re-evaluates the threat table and updates the BB key for the highest-threat target
BTService_WC_MonitorSquadMonitors squad health, broadcasts squad events when members die or retreat
BTService_WC_SyncCombatTagsSyncs current combat-state Gameplay Tags (InCombat, LowHealth, Fleeing) to Blackboard for use by decorators
BTService_WC_AttributeMonitorPolls a set of attributes and writes their values to Blackboard for downstream decorator use

🗺️ EQS Integration

GAS Ally extends the Environment Query System so your AI can make spatial decisions that account for GAS-aware concepts like threat, cover, and ally grouping.

Custom EQS Contexts

Context ClassReturns
UWCEQSContext_HighestThreatTargetThe actor with the highest threat value in the querier's threat table
UWCEQSContext_SquadMembersAll living members of the querier's squad
UWCEQSContext_LowHealthAllyThe ally (in squad) with the lowest health percentage — for support AI
UWCEQSContext_NearestEnemyThe nearest actor with a hostile faction relation to the querier

Custom EQS Tests

Test ClassWhat It Scores
UWCEQSTest_AttributeValueScore candidate locations by a nearby actor's attribute value (e.g. "find position near low-health enemy")
UWCEQSTest_ThreatRangeScore based on distance from high-threat actors — used for flanking positioning
UWCEQSTest_StatusEffectPresentFilter candidates by whether nearby actors have/lack a specific status effect
UWCEQSTest_FactionRelationFilter candidates by faction relationship (Hostile, Neutral, Friendly) to the querier

🔄 StateTree Tasks & Conditions

GAS Ally provides StateTree integration for high-level AI state management. StateTree is ideal for modeling the AI's overarching behavioral mode (Patrol, Combat, Retreat, BossPhase1, BossPhase2, etc.) while Behavior Trees handle the moment-to-moment decision-making within each state.

StateTree Tasks (WCGASAlly)

Task ClassDescription
FWCSTTask_EnterCombatRegisters the AI with the Combat AI Subsystem, sets up threat table, notifies squad
FWCSTTask_ExitCombatClears threat table, removes combat tags, notifies squad of retreat
FWCSTTask_ExecuteBossPhaseApplies the Boss Phase GE set (stat changes, new abilities, visual changes) for a given phase index
FWCSTTask_ApplyWorldContextManually pushes a World Context effect stack (for boss arenas that change environment)
FWCSTTask_BroadcastSquadEventBroadcast a squad event tag to all registered squad members via the subsystem

StateTree Conditions (WCGASAlly)

Condition ClassEvaluates
FWCSTCond_HasGameplayTagTrue if the bound actor has a specific Gameplay Tag
FWCSTCond_AttributeBelowTrue when an attribute value is below a threshold (e.g. Health < 30%)
FWCSTCond_BossPhaseReadyTrue when health crosses a boss phase threshold
FWCSTCond_SquadAliveTrue if a minimum number of squad members are still alive

👥 Squad System

The Squad System allows groups of AI characters to coordinate their behavior as a tactical unit. Squads share threat information, can issue commands to each other, and behave collectively in combat.

WCSquadData Asset

PropertyDescription
SquadTagUnique tag for this squad type, e.g. WC.Squad.BanditRaiders
MaxSizeMaximum squad members (overrides global setting for this squad)
RoleAssignmentTMap of role tags to max count (e.g. 1 Tanker, 2 Flankers, 1 Healer)
SharedThreatPercentWhat percentage (0–1) of one member's threat is shared with all other members
FormationPresetOptional formation data for pathfinding in coordinated movement
SquadLeaderClassAI controller class used for the squad leader (first member registered)

How Squads Work

  1. AI characters register themselves with the UWCCombatAISubsystem on BeginPlay via their WCCombatAIComponent.
  2. Members are grouped into squads based on their SquadData asset tag.
  3. The first member to register becomes the Squad Leader.
  4. When a squad member generates threat (by attacking, receiving damage, using abilities), a percentage is broadcast to all other members.
  5. Squad commands (e.g. "FlankLeft", "FocusFire", "Retreat") are sent via BTTask_WC_CallSquadAction and received by all members listening via BTService_WC_MonitorSquad.
ℹ️
Spawning Squads: The simplest way to create a squad is to spawn a group of AI actors that all reference the same WCSquadData asset on their WCCombatAIComponent. They automatically self-organize into a squad at runtime — no explicit squad manager actor needed.

🎯 Threat System

The Threat System determines which target an AI focuses on at any given moment. It is more nuanced than simple distance-based targeting — it models an AI's awareness of who poses the greatest strategic threat.

WCThreatData Asset

PropertyDescription
BaseThreatOnDamageThreat gained per point of damage dealt to this AI
ThreatOnHealThreat gained when target heals an ally
ThreatOnAbilityUseFlat threat added when the target uses any Gameplay Ability near this AI
TagThreatModifiersTMap — tag presence multiplies threat generation. E.g. WC.Role.Healer × 1.5 (tanks focus healers more)
DecayIntervalSeconds between threat decay ticks (overrides global setting)
DecayRateFraction of threat lost per decay tick for targets not currently attacked
MaxThreatTargetsHow many targets this AI tracks simultaneously in its threat table

Threat Modifiers from GAS Events

Threat is automatically generated when the threat system intercepts Gameplay Events sent to the AI's ASC:

Event TagEffect on Threat Table
WC.Event.DamageTakenAdds threat to the instigator equal to damage × BaseThreatOnDamage
WC.Event.AbilityUsedNearbyAdds flat threat to the ability user
WC.Event.AllyHealedAdds threat to the healer equal to heal amount × ThreatOnHeal
WC.Event.TauntReceivedOverrides current target to the taunter for Taunt duration

👑 Boss Phase System

The Boss Phase System allows AI bosses to dramatically change their behavior, abilities, and stats at specific health thresholds — without any special-casing in code.

WCBossPhaseData Asset

PropertyDescription
BossTagUnique tag for this boss type, e.g. WC.Boss.DragonLord
PhasesOrdered array of FWCBossPhase structs, from Phase 1 (full health) to Phase N (near death)

Boss Phase Struct (FWCBossPhase)

PropertyDescription
PhaseIndexZero-based phase index (0 = first/full-health phase)
HealthPercentThresholdHealth % at or below which this phase activates (e.g. 0.75 = below 75% health triggers Phase 2)
PhaseTagTag added to boss's ASC when in this phase (for decorators and conditions)
OnEnterGameplayEffectsGEs applied when entering this phase (stat changes, ability grants, immunity windows)
OnExitGameplayEffectsGEs removed (or reverse GEs applied) when leaving this phase
AbilitiesToGrantNew abilities unlocked in this phase (e.g. AoE fire breath at Phase 2)
AbilitiesToRevokeAbilities lost when entering this phase
BehaviorTreeOverrideOptional BT asset that replaces the current Behavior Tree for this phase
MontageToPlayOptional montage played as a cinematic transition into this phase
bGrantInvincibilityIf true, applies a damage immunity GE for TransitionDelay seconds during phase intro

Setting Up a Boss

  1. Create Boss Phase Data

    Right-click → Data Asset → WCBossPhaseData. Add phases — e.g. Phase 0 (100%), Phase 1 triggers at 70% health, Phase 2 at 40%, Phase 3 (final) at 15%.

  2. Assign to the Combat AI Component

    On the boss AI character Blueprint, select WCCombatAIComponent and set Boss Phase Data to your new asset.

  3. Create Phase-Specific Gameplay Effects

    For each phase, create GEs for the stat changes. Example: Phase 2 GE grants +50% movement speed, +30% attack, removes slow walk animation tag.

  4. Add Phase Decorators to BT

    In your boss's Behavior Tree, use BTDecorator_WC_IsInBossPhase on branches to run different logic per phase. Alternatively, specify a BehaviorTreeOverride per phase in the Data Asset for a complete swap.

  5. Test

    Use console command WCBoss.ForcePhase <PhaseIndex> on the boss actor to instantly trigger a phase transition for testing.

🌍 World Context System

The World Context System lets the environment itself apply GAS effects to characters. Place AWCWorldContextVolume actors in your world and characters automatically receive configured Gameplay Effects while inside the volume — and have them removed on exit.

Use Cases

  • Lava Zone: Characters inside take periodic fire damage (a ticking GE)
  • Blizzard Area: Speed and regen are penalized (debuff GE)
  • Sacred Grove: Health regeneration greatly increased (buff GE)
  • Dark Cavern: Perception/vision attributes reduced (debuff GE)
  • Day/Night: Bridge to the Calendar subsystem — daytime gives different bonuses than night

AWCWorldContextVolume Setup

  1. Place the Volume

    Search Content Browser or the Place menu for WCWorldContextVolume. Drag it into the level. Resize with the standard Unreal brush tools to cover your environmental area.

  2. Create World Context Data

    Right-click → Data Asset → WCWorldContextData. Configure:

    • ContextTag: e.g. WC.WorldContext.LavaZone
    • GameplayEffectsToApply: Add your lava damage GE (Infinite duration, periodic tick, fire damage)
    • AffectedActorFilter: Which actor classes react (leave empty for all actors with ASC)
    • Priority: When multiple volumes overlap, higher priority wins or combines (configurable)
  3. Assign to the Volume

    Select your placed volume actor and in the Details panel, set World Context Data to your new asset.

WCWorldContextBridge

The UWCWorldContextBridge component links the World Context System to other systems (Calendar, Difficulty). It allows context effects to change dynamically — for example, a forest volume that applies different GEs at night vs. daytime based on a Calendar query.

// The Bridge queries the calendar and applies conditionally:
// WorldContext Volume: "Enchanted Forest"
// Day Context: GE_ForestRegen (health regen bonus)
// Night Context: GE_ForestHunted (periodic fear chance)
// Bridge reads UWCCalendarSubsystem::GetCurrentTimeOfDay() each tick

🔄 Transfer System

The Transfer System provides a structured mechanism for moving attribute values, abilities, or Gameplay Effects between actors at runtime. This powers mechanics like:

  • Life Drain: Attacker steals Health from target
  • Mana Siphon: Spell drains target Mana, adds it to caster Mana
  • Buff Transfer: Support ability moves a buff GE from caster to ally
  • Curse Transfer: Cleanse spell moves a status effect from ally to enemy

Transfer Types (WCTransferTypes)

Transfer TypeWhat is TransferredDirection
AttributeValueA specific amount of an attribute valueSource → Target or bidirectional
GameplayEffectAn active GE instance (by tag)Source → Target
StatusEffectA WCStatusEffectDefinition instanceSource → Target (moves, not copies)
AbilityA granted abilitySource loses it, Target gains it

Executing a Transfer

// Blueprint via UWCTransferFuncLib:
// Transfer 50 Health from Target to Caster (Life Drain)
FWCTransferRequest Request;
Request.TransferType = EWCTransferType::AttributeValue;
Request.AttributeTag = FGameplayTag::RequestGameplayTag("WC.Attribute.Health");
Request.Amount = 50.f;
Request.Source = TargetActor;   // Where value comes FROM
Request.Destination = CasterActor; // Where value GOES TO
Request.bCappedBySourceCurrent = true; // Don't drain more than target has

UWCTransferSubsystem::ExecuteTransfer(GetWorld(), Request);

⚙️ Difficulty System

The Difficulty System applies global multipliers and modifiers across all characters based on the active difficulty tier. It is a Game Instance Subsystem, so it persists across level loads.

WCDifficultyTier Asset

PropertyDescription
TierTage.g. WC.Difficulty.Hard
DisplayName"Hard", "Nightmare", etc.
EnemyDamageMultiplierGlobal multiplier on all AI damage output. 1.5 = 50% more damage.
EnemyHealthMultiplierScales all enemy Max Health attributes on spawn
PlayerHealingMultiplierScales all healing received by players
XPMultiplierScales XP granted from all sources
GlobalGameplayEffectsGEs applied to all actors on difficulty change (e.g. a passive "Hard Mode" GE that gives enemies extra abilities)
// Change difficulty tier at runtime (from main menu, settings, etc.)
if (UWCDifficultySubsystem* Difficulty = GetGameInstance()->GetSubsystem<UWCDifficultySubsystem>())
{
    Difficulty->SetDifficulty(DA_WC_Difficulty_Nightmare);
}

⚔️ Faction System

The Faction System defines relationships between groups of actors. It drives AI target selection (attack enemies, help allies), EQS queries, and UI display of faction standing.

WCFactionRelations Asset

A faction relations asset defines all faction-to-faction relationships. Each entry is a pair of faction tags and a relationship type:

Relationship TypeBehavior Impact
HostileAI with this faction attacks actors of the other faction on sight. EQS threat contexts return these actors.
NeutralNeither attacks nor helps. EQS ignores for targeting but not for blocking.
FriendlyAI helps defend against Hostile actors. Squad system may bridge across friendly factions.
AlliedDeep alliance — shares threat tables, coordinates squad actions across faction lines.

WCFactionAgent Component

Add UWCFactionAgentComponent to any actor to make it faction-aware:

// Get this actor's current faction tag
FGameplayTag Faction = FactionAgent->GetCurrentFaction();

// Change faction at runtime (e.g. player betrays their guild)
FactionAgent->SetFaction(FGameplayTag::RequestGameplayTag("WC.Faction.Bandits"));

// Query relationship between two actors
EWCFactionRelationship Relation = 
    UWCFactionLibrary::GetRelationship(ActorA, ActorB);

💧 Overflow System

The Overflow System handles what happens when an attribute receives more modification than it can absorb. Instead of silently discarding excess, overflow can be routed to another attribute or system.

Common Use Cases

ScenarioOverflow Routing
Healed beyond Max HealthExcess healing → Shield attribute (temporary HP buffer)
Mana gained beyond Max ManaExcess Mana → Arcane Overflow Pool (triggers a special ability when full)
Stamina fills completelyExcess Stamina → Boost Charge (powers a sprint burst)
Damage reduced to 0 by armorOverkill reduction → Stored as Momentum (next attack bonus)

Configuring Overflow

Overflow rules are configured per-attribute in the WCGASAttributeDefinition. Set:

  • OverflowAttributeTag: The attribute that receives overflow (e.g. WC.Attribute.Shield)
  • OverflowMultiplier: How much of the overflow is transferred (0.0–1.0). 1.0 = full overflow, 0.5 = half.
  • OverflowEventTag: Gameplay Event sent when overflow occurs (bind for VFX or ability triggers)
  • bClearOnThreshold: If true, once overflow attribute fills, it is cleared and OverflowEventTag fires

🔬 Deep Dive: Custom Attributes Advanced

While the Attribute Definition Data Asset covers most cases, some games need fully custom attribute behavior. Here is the complete process for creating an attribute system extension in C++.

Step 1 — Create an Attribute Definition Asset

Even for custom attributes, always start with a WCGASAttributeDefinition Data Asset. Set the attribute tag to your new tag, configure base/min/max, and register it in Project Settings. This ensures it is part of the pool.

Step 2 — Create a Custom MMC (if needed)

If your formula type is Custom, subclass UGameplayModMagnitudeCalculation:

UCLASS()
class UMyGame_MMC_ManaFromIntelligence : public UGameplayModMagnitudeCalculation
{
    GENERATED_BODY()
public:
    UMyGame_MMC_ManaFromIntelligence();

    virtual float CalculateBaseMagnitude_Implementation(
        const FGameplayEffectSpec& Spec) const override;

private:
    FGameplayEffectAttributeCaptureDefinition IntelligenceDef;
};

// In .cpp
UMyGame_MMC_ManaFromIntelligence::UMyGame_MMC_ManaFromIntelligence()
{
    // Capture Intelligence attribute from the Source
    IntelligenceDef = FGameplayEffectAttributeCaptureDefinition(
        UWCAttributeSet::GetIntelligenceAttribute(), // Get via pool accessor
        EGameplayEffectAttributeCaptureSource::Source,
        false // don't snapshot
    );
    RelevantAttributesToCapture.Add(IntelligenceDef);
}

float UMyGame_MMC_ManaFromIntelligence::CalculateBaseMagnitude_Implementation(
    const FGameplayEffectSpec& Spec) const
{
    FAggregatorEvaluateParameters Params;
    Params.SourceTags = Spec.CapturedSourceTags.GetAggregatedTags();
    float Intelligence = 0.f;
    GetCapturedAttributeMagnitude(IntelligenceDef, Spec, Params, Intelligence);
    return Intelligence * 5.0f; // 1 Intelligence = 5 Max Mana
}

Step 3 — Reference the MMC in a Gameplay Effect

Create a Gameplay Effect. Add a Modifier targeting your attribute with Magnitude Calculation Class set to your custom MMC. Apply this GE on character init (or via the Attribute Initializer component).

Step 4 — Listen for Changes

// Bind to attribute changes for reactive UI or logic
ASC->GetGameplayAttributeValueChangeDelegate(
    UWCAttributeSet::GetAttributeFromTag(MyAttributeTag)
).AddUObject(this, &ThisClass::OnMyAttributeChanged);

🔬 Deep Dive: Custom Status Effects Advanced

Beyond data-driven effects, you can create fully custom status effect behavior by subclassing the status processing pipeline.

Custom Per-Tick Processing

If a data-driven Tick GE isn't enough, implement a custom UWCStatusEffect_CustomTick class:

UCLASS()
class UMyStatus_FrostbiteTick : public UWCStatusEffect_CustomTick
{
    GENERATED_BODY()
public:
    virtual void ProcessTick(
        UAbilitySystemComponent* TargetASC,
        const FWCStatusEffectState& State,
        float DeltaTime) override
    {
        // Scale damage with current stack count
        float Damage = State.CurrentStacks * 3.0f;

        // Apply damage GE manually
        FGameplayEffectContextHandle Context = TargetASC->MakeEffectContext();
        // ... apply your custom GE
    }
};

Custom Evolution Conditions

For evolution conditions beyond the built-in triggers, subclass UWCStatusEvolutionCondition:

UCLASS()
class UMyEvolution_MoonlightCondition : public UWCStatusEvolutionCondition
{
    GENERATED_BODY()
public:
    virtual bool EvaluateCondition(
        UAbilitySystemComponent* TargetASC,
        const FWCStatusEffectState& State) const override
    {
        // Evolve only at night (reading the calendar subsystem)
        UWCWorldContextSubsystem* WorldCtx = GetWorld()->GetSubsystem<UWCWorldContextSubsystem>();
        return WorldCtx && WorldCtx->IsNightTime();
    }
};

🔬 Deep Dive: Custom Resistance Rules Advanced

If you need resistance behavior beyond the four standard layers (e.g. block-based parry mechanics, damage reflection, conditional resistance), you can inject custom resistance logic into the pipeline.

The Resistance Pipeline Hook

Override UWCResistanceComponent::OnPreDamageApplied in a Blueprint subclass of the component — or in C++ via the delegate:

// C++: Bind to the pre-damage delegate on the component
ResistanceComp->OnPreDamageApplied.AddDynamic(
    this, &ThisClass::CustomResistanceHook);

void AMyCharacter::CustomResistanceHook(
    FWCDamageInfo& DamageInfo)
{
    // Reflect 20% of physical damage back at the attacker
    if (DamageInfo.DamageTypeTag.MatchesTag(TAG_DamageType_Physical))
    {
        float Reflected = DamageInfo.FinalDamage * 0.2f;
        // Apply reflected damage to DamageInfo.Instigator
        // Reduce DamageInfo.FinalDamage by reflected amount
        DamageInfo.FinalDamage -= Reflected;
    }
}

🔬 Deep Dive: Custom Heritage Blessings Advanced

Heritage Blessings are special passive effects that go beyond simple attribute modifiers. They are defined as a combination of a Gameplay Tag, a Gameplay Effect, and optional Blueprint logic.

Creating a Complex Blessing

Example: "Dragon's Blessing" — while the character is below 30% health, they deal 50% more damage.

  1. Create the Conditional GE

    Create a Gameplay Effect with a Modifier on your damage output attribute. Set Modifier Magnitude to use a Conditional formula type (from the 12 formula types list). The condition tag: WC.Status.LowHealth.

  2. Create the "LowHealth" Tag Setter

    Create a second Gameplay Effect that adds tag WC.Status.LowHealth and remove it when not triggered. Use a GE with a Health threshold checker — or use a custom UWCGEComponent_AttributeThresholdTag component on the GE that automatically adds/removes the tag when the attribute crosses 30%.

  3. Add Both GEs to the Blessing

    In the WCHeritage_RaceDefinition, add both GEs to GrantedGameplayEffects with Infinite duration. They will be active as long as the heritage is applied.

🌐 Multiplayer Guide

GAS Ally is designed server-authoritative from the ground up. All gameplay-critical state modifications happen on the server and replicate to clients. This section documents which systems are server-only, which replicate, and how to avoid common pitfalls.

Replication Summary

SystemAuthorityClient Receives
Attribute ValuesServerReplicated via GAS attribute replication
Level / XPServerReplicated properties on WCLevelingComponent
HeritageServer applies GEsGEs replicate to clients via ASC
Skill Tree nodesServerReplicated TArray<int32> of unlocked node IDs
Status EffectsServerActive GE handles replicate via ASC
Status Stack CountServerReplicated on WCStatusEffectComponent
Resistance DataServer resolvesNot replicated (computed server-side only)
Threat TablesServer onlyNot replicated — AI is always server-authoritative
Squad StateServer onlyNot replicated — AI decisions are server-only
Boss Phase IndexServerReplicated int on WCCombatAIComponent
World Context GEsServer appliesGEs replicate via ASC

Critical Rules

🚨
TMap Replication: Unreal Engine does not natively replicate TMap. Any TMap used for networked state in GAS Ally (e.g. threat tables, squad assignments) is server-only. Never try to access or display threat data directly on clients — use server RPCs or replicated snapshots.
⚠️
GrantXP, ApplyStatusEffect, TryUnlockNode — all must be called with HasAuthority() or equivalent server check. These functions will do nothing on clients by design. For player-initiated actions (e.g. clicking "Learn Ability"), use a Server RPC or Gameplay Ability to reach the server first.

Prediction

GAS Ally supports Gameplay Ability System's native client-side prediction. For player-initiated abilities:

  • Activate abilities through the GAS standard TryActivateAbility path — this automatically uses prediction keys
  • Status Effect visuals (VFX, UI icons) can be client-predicted by listening to GAS OnGameplayEffectAdded with the status tag
  • Never predict damage values on clients; damage always resolves server-side

Testing Multiplayer Locally

  1. Set Player Count

    In the Unreal Editor toolbar, set Play As: 2 Players in the Play dropdown.

  2. Use Net Mode: Listen Server

    Set Net Mode: Play As Listen Server so one client is also the server — ideal for local co-op testing.

  3. Monitor Replication

    Use WCGASDebugCommands console commands (see Debug section) to inspect attribute values and active GEs on both the server and client windows simultaneously.

📋 Class Reference

Runtime Module (WCGASAlly) — Key Classes

ClassTypeDescription
UWCHeritageComponentActorComponentApplies Heritage Sets to ASC; saves/loads heritage state
UWCLevelingComponentActorComponentTracks XP and level; fires level-up rewards
UWCSkillTreeComponentActorComponentManages skill tree node unlocks and point pools
UWCStatusEffectComponentActorComponentManages active status effects, stacks, evolution
UWCResistanceComponentActorComponentManages multi-layer resistance data
UWCAutoRegenComponentActorComponentDrives tick-based attribute regen/degen
UWCAbilityCurriculumComponentActorComponentAbility learning system with cost/prerequisite enforcement
UWCFeatComponentActorComponentTracks feat counters and fires milestone rewards
UWCCombatAIComponentActorComponentAI hub: squad membership, threat table, boss phases
UWCRegenSubsystemWorldSubsystemGlobal regen tick orchestrator
UWCStatusEffectSubsystemWorldSubsystemGlobal status effect registry and evolution processor
UWCLevelingSubsystemWorldSubsystemCentralized XP event router
UWCEventsSubsystemWorldSubsystemGlobal event bus for all GAS Ally events
UWCWorldContextSubsystemWorldSubsystemManages active world context volumes and their GEs
UWCCombatAISubsystemWorldSubsystemManages squad registrations and boss phase orchestration
UWCDifficultySubsystemGameInstanceSubsystemPersists difficulty tier across map loads
UWCTransferSubsystemWorldSubsystemExecutes transfer requests between actors
UWCOverflowSubsystemWorldSubsystemRoutes attribute overflow to configured destinations
UWCGASExecCalc_DamageGameplayEffectExecutionCalculationFull damage pipeline with resistance, crit, and events
UWCGASExecCalc_HealingGameplayEffectExecutionCalculationHealing pipeline with overflow support
UWCGASMMCalc_AttributeModModMagnitudeCalculationUniversal attribute modifier supporting all 12 formula types
UWCGASMMCalc_PercentRegenModMagnitudeCalculationPercentage-of-max regen calculator
UWCGASMMCalc_DegenerationModMagnitudeCalculationTag-conditional degeneration calculator
AWCWorldContextVolumeActor (Volume)Brush volume that applies context GEs to overlapping actors
UWCFactionAgentComponentActorComponentMakes an actor faction-aware for AI targeting and EQS

Editor Module (WCGASAllyEditor) — Key Classes

ClassTypeDescription
UWCAttributeDefinitionFactoryUFactoryEnables right-click → Data Asset creation for attribute definitions
UWCHeritageFactoryUFactoryFactory for Race, Class, Subrace, and Heritage Set assets
UWCSkillTreeFactoryUFactoryFactory for Skill Tree Preset assets
UWCStatusEffectFactoryUFactoryFactory for Status Effect Definition assets
UWCResistanceDataFactoryUFactoryFactory for Resistance Data assets
UWCBossPhaseDataFactoryUFactoryFactory for Boss Phase Data assets
UWCAttributeValidatorUEditorValidatorValidates all attribute definitions at save/cook time

🏷️ Tag Reference

GAS Ally uses the WC.GASAlly.* tag namespace. All tags are defined in the WCGASAlly module's tag files and should not be duplicated in your project.

Character State Tags

TagSet When
WC.State.InCombatCharacter has an active combat target
WC.State.DeadCharacter health has reached 0
WC.State.StunnedCharacter cannot take actions
WC.State.LowHealthHealth below configured threshold (default 30%)
WC.State.ImmuneImmunity GE is active — damage is blocked
WC.State.FleeingAI is in retreat state (health critically low)

Status Effect Tags (Common Examples)

TagMeaning
WC.Status.BurningFire damage over time
WC.Status.PoisonedNature damage over time
WC.Status.FrozenMovement and action penalty
WC.Status.WetIncreases lightning damage taken; synergy target
WC.Status.BleedingDelayed physical DoT
WC.Status.StunnedComplete action lockout

Damage Type Tags

TagDamage Category
WC.DamageType.PhysicalPhysical / melee damage
WC.DamageType.FireElemental fire damage
WC.DamageType.LightningElemental lightning damage
WC.DamageType.IceElemental ice damage
WC.DamageType.PoisonNature/poison damage
WC.DamageType.ArcanePure magical damage
WC.DamageType.ElementalParent tag for all elemental types
WC.DamageType.AnyGlobal fallback — matches all damage types

Event Tags

TagFired When
WC.Event.DamageTakenCharacter receives final damage (after all resistance)
WC.Event.HealedCharacter's health is restored
WC.Event.LevelUpCharacter level increases
WC.Event.StatusEffectEvolvedA status effect has evolved to a new form
WC.Event.SynergyTriggeredA status synergy combo fired
WC.Event.EnemyKilledAn enemy was killed (send to killer's ASC for feat tracking)
WC.Event.BossPhaseChangedBoss transitions to a new phase
WC.Event.TauntReceivedAI receives a taunt, overriding threat target

Heritage Tags

Tag PatternPurpose
WC.Heritage.Race.*Race identifiers (e.g. WC.Heritage.Race.Human)
WC.Heritage.Class.*Class identifiers (e.g. WC.Heritage.Class.Warrior)
WC.Heritage.Subrace.*Subrace identifiers
WC.Heritage.Blessing.*Blessing identifiers

📐 Blueprint API

GAS Ally exposes a comprehensive set of Blueprint function libraries so you can access all systems without writing C++.

UWCHeritageLibrary

FunctionDescription
ApplyHeritageSet(Character, HeritageSet)Apply a Heritage Set to a character (calls component; server only)
GetActiveRaceTag(Character)Returns the Gameplay Tag of the character's current race
GetActiveClassTag(Character)Returns the Gameplay Tag of the character's current class
HasBlessing(Character, BlessingTag)Returns true if the character has a specific heritage blessing active

UWCLevelingLibrary

FunctionDescription
GrantXP(Character, Amount)Grant XP and trigger level-up if threshold crossed (server only)
GetCurrentLevel(Character)Returns the character's current level
GetXPProgress(Character)Returns 0.0–1.0 progress toward next level (safe to call on clients)
GetXPToNextLevel(Character)Returns exact XP remaining until next level

UWCStatusEffectLibrary

FunctionDescription
ApplyStatusEffect(Target, Definition, Instigator)Apply a status effect (server only)
RemoveStatusEffect(Target, StatusTag)Remove all stacks of a status effect
GetStackCount(Target, StatusTag)Returns the current stack count for a status effect
IsStatusEffectActive(Target, StatusTag)Returns true if the status is currently active
GetActiveStatusEffects(Target)Returns an array of all active status effect definitions

UWCResistanceLibrary

FunctionDescription
GetEffectiveDamage(Target, RawDamage, DamageTypeTag)Compute final damage after all resistance layers (for preview/tooltip)
GetTotalAbsorption(Target, DamageTypeTag)Returns total effective absorption % for a damage type
RegisterResistanceData(Character, Data)Add a resistance data asset to a character's resistance component

UWCFactionLibrary

FunctionDescription
GetRelationship(ActorA, ActorB)Returns the faction relationship between two actors (Hostile/Neutral/Friendly/Allied)
IsHostile(ActorA, ActorB)Quick boolean check for hostility
SetActorFaction(Actor, FactionTag)Change an actor's faction at runtime

UWCDamageCalcLibrary

FunctionDescription
CalculatePhysicalDamage(Attacker, Defender)Preview physical damage without applying it
CalculateMagicalDamage(Attacker, Defender)Preview magical damage without applying it
WillCritical(Attacker)Roll and return whether next hit would crit (uses CritChance attribute)

🐛 Debug & Console Commands

GAS Ally provides a rich set of debug tools accessible via the console (tilde key ~ or `) and via the Gameplay Debugger.

Gameplay Debugger

Press ` (backtick) in PIE, then press 5 to activate the WCGASAlly debug category. Click any character to inspect their live GAS Ally state:

  • All attribute current/base/max values from the pool
  • Active status effects with stack counts and remaining duration
  • Active Gameplay Effects and their expiry timers
  • Threat table (for AI characters)
  • Boss phase index (for bosses)
  • Heritage race/class tags
  • Current level and XP progress

Console Commands

CommandDescription
WCAttr.Set <Tag> <Value>Force-set an attribute to a value on the selected/focused actor
WCAttr.PrintPrint all attribute values for the selected actor to the Output Log
WCStatus.Apply <StatusTag>Apply a status effect (by tag) to the selected actor
WCStatus.Remove <StatusTag>Remove a status effect from the selected actor
WCStatus.Evolve <StatusTag>Force-trigger all evolution rules for a given status tag immediately
WCLevel.Set <Level>Force the selected character to a specific level (skips XP)
WCLevel.GrantXP <Amount>Grant XP to the selected character
WCBoss.ForcePhase <PhaseIndex>Force a boss phase transition to a specific phase index
WCThreat.PrintPrint the threat table of the selected AI to the Output Log
WCThreat.ClearClear all threat entries for the selected AI
WCDifficulty.Set <TierTag>Set global difficulty tier by tag
WCResist.PrintLayersPrint all resistance layers and values for the selected actor
WCDebug.AttributeHUDToggle an on-screen HUD showing real-time attribute values for the player character
💡
Enable bEnableDebugLogging in Project Settings → WC GAS Ally for verbose LogWCGASAlly output in the Output Log. This logs every attribute change, status effect apply/remove, evolution, and subsystem event — invaluable during development but should be disabled in shipping builds.

🔧 Troubleshooting

Build Errors

ErrorLikely CauseFix
"Cannot find module WCGASAlly"Plugin not properly installed or Plugins folder not generatedVerify plugin is in Plugins/ folder; right-click .uproject → Generate VS project files; rebuild
"GameplayAbilities module not found"GameplayAbilities engine plugin disabledEnable GameplayAbilities in Edit → Plugins; the DynamicRPGWorlds .uplugin should do this automatically
C2259 / Abstract class instantiation errorSubclassing a GAS Ally class and not implementing all pure virtual functionsCheck which virtual functions your override must implement; see class header for = 0 declarations

Runtime Issues

ProblemLikely CauseFix
Attributes all show 0 at runtimeAttribute Definitions not registered in Project Settings → WCGASCoreAdd all Definition assets to the Attribute Definitions array in settings
Heritage has no effect on attributesApplyHeritageSet called on client, not serverEnsure the call is wrapped in HasAuthority() or called via a Server RPC
Status effects not evolvingEvolution rules not registered in Global Settings or not linked to effectAdd evolution rules to Project Settings → WC GAS Ally → Global Status Evolution Rules
Skill Tree points not grantingLevelUpRewards not configured in WCLevelingRules assetOpen your WCLevelingRules asset; check LevelUpRewards TMap has entries with SkillPointsGranted > 0
AI not targeting playerFaction relations not configured or WCFactionAgentComponent missingAdd WCFactionAgentComponent to both player and AI; configure WCFactionRelations asset
Boss phases not triggeringBossPhaseData not assigned or HealthPercentThreshold set incorrectlyCheck WCBossPhaseData; thresholds should be descending (0.75, 0.40, 0.15). Verify WCCombatAIComponent has data assigned
World Context volume GEs not applyingAWCWorldContextVolume has no collision or wrong filterCheck Brush Collision profile; ensure AffectedActorFilter includes your character class
"LogWCGASAlly: Warning: Pool full"More than 150 attribute definitions registeredIncrease AttributePoolSize in WCGASCoreSettings or reduce your attribute count

Performance Issues

SymptomCauseSolution
Frame drops when many AI are activeToo many BT nodes querying ASC every tickUse BTService_WC_SyncCombatTags to cache values in Blackboard; reduce service tick intervals
Hitches every 0.25 secondsRegen subsystem tick processing many actorsIncrease RegenTickInterval in settings (0.5–1.0s is acceptable for most games)
Status effect synergy causing lagToo many global synergy rules evaluated per frameReduce synergy rule count; use per-actor inline rules for rare synergies instead of global rules
ℹ️
Getting Help: When reporting issues, always include: UE version, plugin version (visible in the .uplugin file as VersionName), the relevant Output Log section (enable debug logging first), and the steps to reproduce. Check the Wonderscape Creations FAB Marketplace page for known issues and patch notes.