Dynamic RPG Worlds
Complete beginner-to-expert documentation — step-by-step assembly guides, walkthroughs, and full reference for the Wonderscape Creations RPG Framework
Overview
Dynamic RPG Worlds is a comprehensive Unreal Engine 5.7+ plugin framework by Wonderscape Creations. It gives you a production-ready foundation for open-world RPGs — covering combat, inventory, interaction, AI, adaptive audio, dynamic NPC society simulation, and more. Every system is built on three pillars:
Designer-First
No hardcoded values. Every system is controlled through Project Settings and Blueprint-exposed Data Assets.
Multiplayer-Ready
Client-server from day one. All gameplay-critical operations are server-authoritative with full replication.
GAS-Centric
Gameplay Ability System powers every mechanic — abilities, effects, and attributes are first-class citizens.
Modular
13 independent modules. Adopt one or all. No monolithic dependencies between feature modules.
Fragment-Based
Both items and abilities use composable fragments — configure rich behaviors without C++ subclassing.
FAB Ready
Built to Epic's marketplace standards. Only modern UE 5.7+ APIs — zero deprecated code.
Prerequisites
Engine & Platform
| Requirement | Minimum | Notes |
|---|---|---|
| Unreal Engine | 5.7.0 | Plugin targets UE 5.7+. Earlier versions are NOT supported. |
| Platform | Win64 | Win64 only per .uplugin manifest. Other platforms not yet supported. |
| Visual Studio | 2022 | Install the "Game development with C++" workload. |
| C++ Compiler | MSVC (VS 2022) | Required to build the plugin modules. |
Required UE Plugins (Auto-Enabled)
The .uplugin file enables these automatically. You do not need to enable them manually:
| Plugin | Purpose |
|---|---|
GameplayAbilities | Core GAS — powers all abilities, effects, and attributes |
EnhancedInput | Modern input system used by WCInput |
StateTree + GameplayStateTree | Hierarchical state machine for AI and complex logic |
GameplayCameras | UE 5.7 data-driven camera rig system |
Mover | New UE 5.5+ character movement framework |
PoseSearch | Motion matching for animation |
AnimationWarping + MotionWarping | Stride warping and root-motion warping for attacks |
Chooser | Data-driven animation selection |
CommonUI | Cross-platform UI framework used by WCUIFramework |
ModelViewViewModel | MVVM data binding for UI widgets |
DataValidation | Editor-time data asset validation |
Installation
-
Install Visual Studio 2022 with the Correct Workload
Open the Visual Studio Installer. Click Modify on VS 2022, then check "Game development with C++". This installs the MSVC compiler toolchain, Windows SDK, and Unreal-compatible build tools. Without this, the plugin will not compile.
If VS 2022 is already installed but you're missing the workload, re-run the installer, click Modify, and add it. A full reinstall is not required. -
Ensure Your Project is a C++ Project
Open your project in the Unreal Editor. If the project is Blueprint-only, convert it now:
- Go to Tools → New C++ Class
- Select None (Empty Class) as the parent, click Next
- Name it
WCSetupand click Create Class - Unreal will generate a
Source/folder and open Visual Studio. You can delete the files afterward — you just needed to trigger the C++ project conversion.
-
Copy the Plugin Folder
Find or create a
Plugins/folder directly inside your project root (same level asContent/and your.uprojectfile). Copy the entireDynamicRPGWorldsfolder into it:YourProject/ ├── Content/ ├── Source/ ├── Plugins/ │ └── DynamicRPGWorlds/ ← Place here │ ├── DynamicRPGWorlds.uplugin │ ├── Source/ │ └── Docs/ └── YourProject.uproject -
Enable the Plugin in the Editor
Open your project in the Unreal Editor. Go to Edit → Plugins. In the search box type Dynamic RPG Worlds. You will see the plugin listed under "Game Design Framework". Check the Enabled checkbox. Click Restart Now when prompted. The editor will close and reopen.
-
Regenerate Project Files
Close the Unreal Editor fully. In Windows Explorer, right-click your
.uprojectfile and select "Generate Visual Studio project files". Wait for the process to complete (a progress dialog will appear). This step adds all 13 plugin modules to your Visual Studio solution so they are found by IntelliSense and the compiler. -
Build the Project
Open the generated
.slnfile in Visual Studio 2022. In the toolbar, set the configuration to Development Editor and the platform to Win64. Press Ctrl+Shift+B to build.First compile takes 5–15 minutes. The plugin has 13 modules with hundreds of C++ files. Subsequent builds are incremental and take seconds. The green status bar at the bottom of Visual Studio shows build progress. A successful build ends with "Build: 1 succeeded, 0 failed". -
Launch the Editor and Verify
Launch the editor from Visual Studio (press F5) or by double-clicking the
.uprojectfile. After it loads, go to Edit → Project Settings. Scroll the left panel — you should see a "Dynamic RPG Worlds" category with sub-entries: General, GAS Core, Input, Interaction, Inventory, Combat, UI, and Audio. If you see these, the plugin is correctly installed and loaded.If the editor crashes on first load, check theSaved/Logs/YourProject.logfile. Search for "Error" or "failed" to identify the module that failed to load. Most first-launch issues are caused by missing VS workload components. -
Verify Plugin Content is Accessible
In the Content Browser, click the Settings button (gear icon) in the top-right and enable "Show Plugin Content". You should now see a DynamicRPGWorlds Content folder in the browser. This contains any pre-made data assets or examples shipped with the plugin.
-
Enable Show Engine Content (Optional)
For GAS-related work, also enable "Show Engine Content" in the same Settings menu. This lets you access engine-level GAS classes like
GameplayEffectblueprints and attribute sets when creating your assets.
Quick Start Guide
Follow these steps to go from a blank project to a fully functional WC RPG character — with movement, input, attributes, inventory, and basic combat all working. Budget about 45–60 minutes for your first run.
Step 1 — Create Blueprint Subclasses of WC Framework Classes
It is best practice to create Blueprint subclasses rather than using the WC classes directly. This gives you a place to add custom Blueprint logic later without touching C++.
For each class, go to the Content Browser, right-click in your project folder, and select Blueprint Class. In the "Pick Parent Class" search box, search for the class name:
| Blueprint Name | Parent Class | Purpose |
|---|---|---|
BP_WC_GameMode | WCGameModeBase | Game rules and default class assignments |
BP_WC_PlayerController | AWCPlayerController | Input routing and UI management |
BP_WC_PlayerState | AWCPlayerState | Holds the ASC, inventory, crafting components |
BP_WC_HUD | AWCHUD | HUD, crosshair, audio director |
BP_WC_GameState | AWCGameStateBase | Replicated game-wide state |
BP_WC_PlayerCharacter | AWCPlayerCharacter | The playable character |
Content/WC/Core/Framework/ to keep your project organized.Step 2 — Assign Framework Classes in Project Settings
Go to Edit → Project Settings → Maps & Modes. Under Default Modes, set each class dropdown to the Blueprint you just created:
- Default GameMode:
BP_WC_GameMode - Player Controller Class:
BP_WC_PlayerController - Player State Class:
BP_WC_PlayerState - HUD Class:
BP_WC_HUD - Game State Class:
BP_WC_GameState
Open BP_WC_GameMode and in the Details panel, set Default Pawn Class to BP_WC_PlayerCharacter.
Step 3 — Configure Your Player Character Blueprint
-
Open BP_WC_PlayerCharacter
Double-click it to open. Switch to the Components panel (top-left). You will see components already attached by the parent class:
CapsuleComponent(root),Mesh(Skeletal Mesh),WCCharacterMovementComponent,WCInteractionComponent, andWCGASAttributeInitializer. -
Assign a Skeletal Mesh
Click on the Mesh component. In the Details panel on the right, find Skeletal Mesh Asset and click the dropdown to select your character's skeletal mesh. Also set the Animation Blueprint (Anim Class) dropdown to your character's Animation Blueprint if you have one.
-
Adjust Capsule Size
Click the CapsuleComponent. In the Details panel, set Capsule Half Height and Capsule Radius to match your mesh proportions. For a standard human, 88 and 34 are common starting values.
-
Position the Mesh
The mesh should sit inside the capsule with feet at the bottom. In the viewport, select the mesh and use the transform gizmo to move it down so feet align with the capsule base. Typically a Z offset of
-88(negative half-height) works for standard humanoids. -
Set Up the Camera
Add a Spring Arm Component (click Add in the Components panel, search "Spring Arm"). Attach it to the root. Then add a Camera Component attached to the Spring Arm. For a third-person game, set the Spring Arm's Target Arm Length to 400 and enable Use Pawn Control Rotation on the Spring Arm.
Step 4 — Create and Register Attribute Definitions
-
Create Attribute Definition Assets
In the Content Browser, right-click → Miscellaneous → Data Asset. In the class picker, search for and select WCGASAttributeDefinition. Click Select. Name it
DA_WC_Attr_Health. Repeat for Stamina, Mana, and any other stats your game needs. -
Configure Each Attribute Definition
Double-click
DA_WC_Attr_Health. Fill in the Details panel:- Display Name: "Health"
- Attribute Tag: Click the dropdown and type
WC.Attribute.Health— select it from the list (it must be a pre-registered WC tag) - Base Value: 100.0 (the starting value for all characters)
- Min Value: 0.0 — bClampToMin: checked
- Max Value: 100.0 — bClampToMax: checked
- bReplicated: checked (health must replicate to all clients)
- Regen Rate: 0.0 for health (unless you want passive regen), 5.0 for stamina
- Regen Interval: 0.25 (how often regen ticks, in seconds)
Click Save. Repeat for each attribute.
-
Register Attributes in Project Settings
Go to Edit → Project Settings → Dynamic RPG Worlds → GAS Core. Find the Attribute Definitions array. Click the + button for each attribute and assign your
DA_WC_Attr_*assets.
Step 5 — Create the Input Setup
-
Create Input Action Assets
In Content Browser, right-click → Input → Input Action. Create one for each player input:
IA_WC_Move— Value Type: Axis2D (Vector2D)IA_WC_Look— Value Type: Axis2D (Vector2D)IA_WC_Jump— Value Type: Digital (bool)IA_WC_Interact— Value Type: Digital (bool)IA_WC_Attack— Value Type: Digital (bool)
-
Create an Input Mapping Context
Right-click → Input → Input Mapping Context. Name it
IMC_WC_Default. Double-click to open it. Click the + button next to Mappings for each Input Action and assign keyboard/mouse keys. For example:IA_WC_Move→ WASD keys with Modifiers. -
Create the WCInputSetupData Asset
Right-click → Miscellaneous → Data Asset → WCInputSetupData. Name it
DA_WC_Input_Default. Open it and configure:- Mapping Contexts: Add your
IMC_WC_Default, Priority: 0 - Handlers: Add one handler per input type (see the WCInput module section for handler details)
- Mapping Contexts: Add your
-
Assign Input Setup to Player Controller
Open
BP_WC_PlayerController. In the Details panel (with nothing selected), find WC | Input → Default Input Setup. Click the dropdown and select yourDA_WC_Input_Defaultasset. This makes the controller apply this input configuration automatically on BeginPlay.
Step 6 — Place a Test Level and Press Play
Open or create a level. Place a Player Start actor. Press Play in the editor. Your character should spawn, and you should be able to move, look around, and jump. Check the Output Log (Window → Output Log) for any warnings. Common early warnings:
"No attribute definitions registered"— You skipped Step 4.3. Add definitions to Project Settings."Input Setup not found"— You skipped Step 5.4. Assign the setup asset to the controller."WCInteractionComponent: No detection mode set"— Normal until you configure interaction. Can be ignored for now.
AWCDummy actor from the Content Browser into your level now. It has a fully configured CombatASC and logs all hits to the Output Log — invaluable for testing combat later.Project Settings Reference
All WC Framework settings live under Edit → Project Settings → Dynamic RPG Worlds. Every module registers its own settings category here.
General (WCProjectSettings)
| Property | Type | Description |
|---|---|---|
DefaultGameModeClass | Class | Override the default WC game mode globally |
bEnableDebugLogging | bool | Enable verbose framework logs across all modules |
GAS Core (WCGASCoreSettings)
| Property | Type | Description |
|---|---|---|
AttributeDefinitions | Array | All WCGASAttributeDefinition assets to register at startup — every attribute your game uses must be here |
AttributePoolSize | int | Size of the pre-generated attribute pool (default: 150). One slot per unique attribute definition. |
bAutoRegisterAttributes | bool | Auto-register attribute definitions at game startup. Keep enabled unless you manage registration manually. |
DefaultAbilityBooks | Array | WCGASAbilityBook assets to load into the global ability library at startup |
Input (WCInputSettings)
| Property | Default | Description |
|---|---|---|
InputBufferDuration | 0.2s | How long a buffered input is kept waiting for the right window to open. Increase for more lenient timing. |
MaxBufferedInputs | 3 | Maximum inputs held in the buffer at once |
ComboWindowDuration | 0.5s | Default time window for combo tree input matching (overridable per node) |
bDebugInputBuffer | false | Show on-screen debug for buffered inputs — enable during development to tune timing |
Interaction (WCInteractionSettings)
| Property | Default | Description |
|---|---|---|
DetectionRange | 250cm | Default interaction detection distance for Trace and CapsuleTrace modes |
HoldDuration | 1.5s | Default time to hold for Hold-type interactions |
bEnableDebugVisualization | false | Draw interaction detection volumes in the editor viewport — enable to verify detection ranges |
bEnableMultiplayerSync | true | Enable cooperative interaction replication. Disable only for single-player games. |
Inventory (WCInventorySettings)
| Property | Default | Description |
|---|---|---|
DefaultMaxStackSize | 64 | Default stack limit for stackable items (overridable per item via WCFragment_Stackable) |
bEnableWeightSystem | true | Enable item weight and carry capacity system |
DefaultBagSlots | 20 | Number of slots in the default player bag |
DefaultExplosionDamageEffect | — | Fallback Gameplay Effect applied when an explosive detonates and no custom damage GE is specified |
Combat (WCCombatSettings)
| Property | Default | Description |
|---|---|---|
TraceMode | MultiPointSweep | MultiPointSweep traces previous-to-current socket position (catches fast swings). SocketPair traces between two sockets in a single frame. |
TraceChannel | ECC_Pawn | Collision channel for melee hit detection. Create a custom channel for your game to avoid hitting environment geometry. |
TraceRadius | 15.0cm | Sphere radius of the sweep trace. Increase for larger weapons, decrease for precision weapons. |
RegisteredCombatStyles | [] | All WCCombatStyleDefinition assets available globally. Add every style your game uses here. |
BaseDamageAttributeTag | — | Tag identifying the base damage attribute on the attacker's ASC |
bEnableClientPrediction | true | Enable client-side hit prediction for responsive melee feel. Server always validates. |
bDebugTraces | false | Draw melee trace debug spheres in the world. Enable to verify trace coverage. |
UI (WCUISettings)
| Property | Description |
|---|---|
bEnableCrosshair | Global crosshair toggle. Set to false to disable crosshair entirely. |
DefaultHUDWidgetClass | HUD widget Blueprint class to spawn. Create a subclass of WCHUDWidget and set it here. |
AimingStateTag | Tag that triggers crosshair visibility. Default: WC.Combat.State.Aiming |
bEnableArmedRangedCrosshair | Also show crosshair when a ranged weapon is drawn, even without aiming |
ArmedRangedStateTag | Tag for "ranged weapon drawn" state. Default: WC.Combat.State.Armed.Ranged |
HitMarkerEventTag | GAS event tag that flashes the hit marker. Default: WC.Combat.Event.HitConfirmed |
ShotFiredEventTag | GAS event tag that kicks crosshair spread. Default: WC.Combat.Event.ShotFired |
CrosshairTargetColors | Array of tag → color mappings for target tinting (enemy = red, friendly = green, etc.) |
Audio (WCAudioSettings)
| Property | Description |
|---|---|
MusicVolume | Global music volume multiplier (0.0–1.0) |
AmbientVolume | Ambient soundscape volume multiplier |
CrossfadeDuration | Default music crossfade time in seconds when transitioning between states |
Module Architecture
The plugin uses a strict 3-layer dependency model. Dependencies flow upward only — lower layers never depend on higher layers.
Integration
Features
Foundation
| Module | Layer | Key Dependencies | Purpose |
|---|---|---|---|
WCGASCore | L1 | Engine only | GAS foundation, attributes, abilities, ASC, all gameplay tags |
WCGASAlly | L2 | WCGASCore | Extended RPG GAS: leveling, heritage, skill trees, resistance, AI |
WCUIFramework | L2 | WCGASCore, CommonUI | HUD, menus, crosshair, themes, MVVM base |
WCInteraction | L2 | WCGASCore, WCUIFramework | World interaction system, 8 interaction types |
WCInventory | L2 | WCGASCore, WCGASAlly, WCInteraction, WCUIFramework | Items, equipment, crafting, loot |
WCCombat | L2 | WCGASCore, WCInventory | Melee, ranged, combos, styles |
WCInput | L2 | WCGASCore, WCCombat, WCInteraction, WCInventory, WCUIFramework | Input routing, buffering, combo detection |
WCAudioSuite | L2 | WCGASCore, WCDynamicSociety | Adaptive music, ambient, stingers |
WCDynamicSociety | L2 | Engine (minimal) | Calendar, factions, crime, social simulation |
DynamicRPGWorlds | L3 | ALL feature modules | Characters, game framework, movement, camera |
Naming Conventions
| Type | Pattern | Example |
|---|---|---|
| All WC classes | WC prefix | WCInventoryComponent |
| Components | WC[Module]Component | WCEquipmentComponent |
| Data Assets | WC[Type]Definition | WCItemDefinition |
| Settings | WC[Module]Settings | WCCombatSettings |
| Subsystems | WC[Purpose]Subsystem | WCItemSubsystem |
| Item Fragments | WCFragment_[Name] | WCFragment_WeaponData |
| Ability Fragments | WCAbilityFragment_[Name] | WCAbilityFragment_MeleeCombat |
| Input Handlers | WCInputHandler_[Name] | WCInputHandler_CombatAbility |
| Blueprint Assets | BP_WC_[Module]_[Name] | BP_WC_Inventory_BasicChest |
| Data Assets (files) | DA_WC_[Module]_[Type]_[Name] | DA_WC_Inventory_Item_HealthPotion |
Character Hierarchy
ACharacter (UE Engine)
└── AWCCharacterBase (Abstract)
│ — State machine (Normal / Dead / Incapacitated / Cinematic / Spawning)
│ — Gameplay tag system + DefaultGameplayTags applied on BeginPlay
│ — Death system: Die() → HandleDeath() → OnDeathFinished()
│ — GAS integration via IAbilitySystemInterface
│ Components: WCCharacterMovementComponent, WCInteractionComponent, WCGASAttributeInitializer
│
├── AWCPlayerCharacter
│ — UGameplayCameraComponent (data-driven rigs via UWCCameraDirector)
│ — ASC is owned by AWCPlayerState (not the character directly)
│ — Use this as base for all player-controlled characters
│
└── AWCAICharacter
— Owns WCCombatAbilitySystemComponent directly
— Use this as base for all NPC/enemy characters
ASC Ownership — Important to Understand
| Character Type | ASC Owner | How to Get ASC in Blueprint |
|---|---|---|
| Player Character | AWCPlayerState | Call GetAbilitySystemComponent() on the character — it automatically routes to PlayerState |
| AI Character | The AWCAICharacter itself | Call GetAbilitySystemComponent() directly on the actor |
| Any actor (unknown type) | Varies | Use Blueprint node GetWCAbilitySystemComponent(Actor) from WCCoreLibrary — handles both cases |
Character States
| State | GAS Tag | Description |
|---|---|---|
| Normal | WC.State.Gameplay.Exploring | Default alive state, full input enabled |
| InCombat | WC.State.Gameplay.Combat | Active combat, may restrict non-combat abilities |
| Dead | WC.State.Gameplay.Dead | Character died; triggers death animations and logic |
| Incapacitated | WC.State.Gameplay.Incapacitated | Alive but cannot act (stunned, knocked down) |
| Cinematic | WC.State.Gameplay.Cinematic | In cutscene; all input disabled |
Module: DynamicRPGWorlds (Integration Core)
DynamicRPGWorlds
Layer 3 Integration — Assembles all feature modules into final game framework classes.
Game Framework Classes
| Class | Purpose |
|---|---|
AWCGameModeBase | Default WC class assignments, game rules foundation |
AWCGameStateBase | Replicated game-wide state |
UWCGameInstance | Persistent instance with level transition hooks (OnPreLevelTransition, OnPostLevelTransition) |
AWCPlayerController | Controller with WCInputManagerComponent, DefaultInputSetup property, and UI stubs |
AWCPlayerState | Server-authoritative state, owns WCCombatAbilitySystemComponent and WCCraftingComponent |
AWCHUD | HUD: spawns the HUD widget, binds ASC events for crosshair, and sets up the audio director |
AWCPlayerCameraManager | Custom camera manager with UE 5.7 FocalLength/FieldOfView bug workaround |
AWCDummy | Debug target — capsule + skeletal mesh + CombatASC. Logs all hits, overlaps, and GAS events. |
Movement System — Locomotion States
| State | Triggered By | Key Property |
|---|---|---|
| Idle | No movement input | Automatic when velocity is zero |
| Walk | StartLocomotion(WalkTag) | WalkSpeed |
| Jog | Default movement | JogSpeed |
| Sprint | StartLocomotion(SprintTag) or sprint ability | SprintSpeed, SprintAccelerationTime (0.3s) |
| Crouch | StartLocomotion(CrouchTag) | CrouchSpeed |
| Custom | Designer-defined | Add via CustomLocomotionStates array |
Speed modifiers stack multiplicatively via AddSpeedModifier(Tag, Multiplier) / RemoveSpeedModifier(Tag). Use these from abilities and effects to slow or accelerate the character.
Camera System
UWCCameraDirector maps gameplay tags to camera rigs via FWCCameraRigMapping (ActivationTag, CameraRig, Priority). Each frame it reads the player's ASC tags and activates the highest-priority matching rig, falling back to DefaultCameraRig. Use cases: ADS zoom rig, sprint camera, crouch camera, stance cameras.
Module: WCGASCore
WCGASCore
Layer 1 Foundation — Core GAS infrastructure: attribute pool, ability definitions, fragments, extended ASC, ability library, and ALL native gameplay tags.
Setting Up Attributes — Detailed Steps
-
Create One WCGASAttributeDefinition Per Stat
For every stat in your game (Health, Stamina, Mana, Strength, Agility, etc.), create a separate Data Asset:
Content Browser → Right-click → Miscellaneous → Data Asset → WCGASAttributeDefinition
Use names like
DA_WC_Attr_Health,DA_WC_Attr_Stamina,DA_WC_Attr_Mana. Store them inContent/WC/Core/Attributes/. -
Configure Every Property in the Definition
Open each attribute definition. Here is every property and what it controls:
Property What It Does Recommended For Health DisplayNameHuman-readable name shown in UI "Health" AttributeTagGameplay tag uniquely identifying this attribute. Must be in WC.Attribute.*hierarchy.WC.Attribute.HealthBaseValueStarting value when an actor is initialized 100.0 MinValueFloor — attribute cannot go below this 0.0 bClampToMinEnable the minimum clamp ✓ checked MaxValueCeiling for normal clamping 100.0 bClampToMaxEnable the maximum clamp ✓ checked bReplicatedReplicate this attribute to all clients. Always on for health/mana/stamina shown in UI. ✓ checked RegenRateAmount regenerated per RegenInterval. 0 = no passive regen.0.0 RegenIntervalSeconds between regen ticks 0.25 DegenRateAmount depleted per tick (for stamina drain during sprint, etc.) 0.0 UIIconOptional icon texture for this attribute in inventory/character screens Heart texture -
Register Definitions in Project Settings
Edit → Project Settings → Dynamic RPG Worlds → GAS Core → Attribute Definitions. Click the + button for each definition asset and assign it. Order matters for pool slot assignment — put frequently-used attributes early in the array.
-
Understand How the Pool Works
At startup, the
WCGASAttributeRegistryreads your definitions array and assigns each one a slot in the pre-generated pool of 150 attributes (Attribute_00throughAttribute_149). So "Health" might become slot 0, "Stamina" slot 1, etc. When an actor is initialized, itsWCGASAttributeInitializercreates aWCGASAttributePoolAttributeSet and grants it to the ASC — giving that actor all 150 slots, with values initialized from BaseValue. -
Verify Attributes are Registered
Press Play. Open the console (~ key) and type:
showdebug abilitysystem. Press Enter. In the top-left of the screen you'll see a green overlay listing all attributes registered on the currently possessed pawn's ASC. You should see all your attribute names with their current values. If an attribute is missing, check that it's in the Project Settings array and that the pool size is large enough. -
Read Attribute Values from Blueprint
To read an attribute value in a Blueprint (e.g., to show in HUD):
- Get the actor's ASC using the
GetWCAbilitySystemComponentnode - Use the
WCGASAttributePoolHelper::GetAttributeValue(ASC, AttributeTag)function, passing the attribute's gameplay tag (e.g.,WC.Attribute.Health) - This returns the current value as a float
For reacting to changes, bind to
WCGASAttributePoolHelper::OnAttributeValueChanged(ASC, AttributeTag, Delegate). This fires whenever the attribute changes, including from effects and regen. - Get the actor's ASC using the
-
Configure Attribute Override Per Character (Optional)
To give a specific NPC different base values than the defaults (e.g., a boss with 500 max health), create a
WCGASAttributeOverrideDataasset. In it, list which attributes to override and with what values. Assign this asset to theWCGASAttributeInitializercomponent on that character's Blueprint.
Ability System Classes
| Class | Role |
|---|---|
UWCAbilitySystemComponent | Extended ASC with definition-based API, delegate broadcasting, montage multicast, starting abilities |
UWCGameplayAbility | Base ability class — definition access, fragment execution, context, per-fragment runtime state storage |
UWCAbilityDefinition | Primary Data Asset defining a complete ability: identity, GAS settings, cost/cooldown, triggers, combo config, fragments |
UWCAbilityFragment | Abstract base for composable ability behaviors. Tag-gated activation with full lifecycle hooks. |
UWCStartingAbilitiesData | Data Asset listing abilities to grant automatically when an actor is initialized |
Module: WCGASAlly
WCGASAlly
Layer 2 Feature — Extended RPG GAS layer: heritage, leveling, skill trees, status effects, resistance, AI. The largest module (~424 header files).
| System | Key Classes | Purpose |
|---|---|---|
| Heritage | WCGASRaceData, WCGASClassData, WCGASSubraceData | Race/class combinations grant stats, abilities, and tags |
| Leveling | WCGASLevelingRulesData, WCGASLevelingSubsystem | XP thresholds, level caps, attribute scaling |
| Skill Tree | WCGASSkillTreeData, WCGASBuildPresetAsset | Unlockable skill nodes with prerequisites and point costs |
| Status Effects | WCGASStatusEffectSubsystem, WCGASEvolutionRules | Effects that evolve into others, synergy chains between effects |
| Resistance | WCGASResistanceSubsystem, WCGASAbsorptionData, WCGASDiminishingData | Multi-layer damage mitigation with diminishing returns |
| AI | BehaviorTree tasks/decorators, StateTree nodes, WCGASSquadComp, WCGASThreatTypes | Combat AI, squad coordination, threat management, boss phases |
| Curriculum | WCGASAbilityCurriculum | Structured ability learning tied to progression milestones |
| Feats | Feat pool system | Selectable character-building bonuses |
| Transfer | WCGASTransferSubsystem | Drain/transfer attributes between actors (lifesteal, healing transfer) |
| World Context | WCGASContextVolume | Environmental volumes that modify attributes (hot zones, cold zones) |
See the Heritage, Skill Tree, and Calendar walkthroughs in the Walkthroughs section for full step-by-step assembly of these systems.
Module: WCInput
WCInput
Layer 2 Feature — Handler-based input routing with Enhanced Input, input buffering for timing-sensitive mechanics, and tree-based combo detection.
Input Flow
Enhanced Input → WCInputManagerComponent → Handlers (sorted by priority) → InputBuffer → ComboDetector
Setting Up Input — Detailed Steps
-
Create Input Actions for Every Player Input
For each physical input your game needs, create an Input Action asset (Right-click → Input → Input Action). The value type is critical:
Input Action Value Type Reason IA_WC_MoveAxis2D (Vector2D) WASD or stick produces a 2D direction IA_WC_LookAxis2D (Vector2D) Mouse delta or right stick produces 2D look IA_WC_JumpDigital (bool) Simple press/release button IA_WC_InteractDigital (bool) Simple press/release button IA_WC_AttackDigital (bool) Simple press/release button IA_WC_HeavyAttackDigital (bool) Hold detection is handled by the Combat handler IA_WC_DodgeDigital (bool) Press-only ability activation IA_WC_SprintDigital (bool) Hold-to-sprint (handled by Locomotion fragment) IA_WC_ToggleInventoryDigital (bool) Menu toggle press -
Create an Input Mapping Context
Right-click → Input → Input Mapping Context. Name it
IMC_WC_Default. Open it. For each Input Action, click the + (Add) button and assign your physical keys. Pay attention to Modifiers for WASD axis mapping:IA_WC_Move+ W key → Add modifier: Swizzle Input Axis Values (YXZ)IA_WC_Move+ S key → Add modifiers: Swizzle Input Axis Values (YXZ) then NegateIA_WC_Move+ A key → Add modifier: NegateIA_WC_Move+ D key → No modifiers (positive X axis)
-
Create the WCInputSetupData Asset
Right-click → Miscellaneous → Data Asset → WCInputSetupData. Name it
DA_WC_Input_Default. This is the central configuration object that bundles everything together. -
Add the Mapping Context
Open
DA_WC_Input_Default. In the Mapping Contexts array, click + and assignIMC_WC_Default. Set Priority to 0 (higher numbers take precedence if you have multiple contexts). -
Add Input Handlers — Movement and Look
In the Handlers array, click + and choose WCInputHandler_Movement. Configure it:
- Input Action:
IA_WC_Move - Priority: 200 (Normal)
- Blocking Tags: Leave empty unless you want to block movement during specific states (e.g., add
WC.State.Gameplay.Cinematicto block movement in cutscenes)
Add another handler WCInputHandler_Look:
- Input Action:
IA_WC_Look - Priority: 200
- Input Action:
-
Add the Jump Handler
Add WCJumpHandler:
- Input Action:
IA_WC_Jump - Priority: 200
- bVariableJumpHeight: true — allows tapping for low jump and holding for high jump (release early to cut jump height)
- Input Action:
-
Add the Interaction Handler
Add WCInputHandler_Interaction:
- Input Action:
IA_WC_Interact - Priority: 200
- This handler automatically finds and calls the
WCInteractionComponenton the player character.
- Input Action:
-
Add Combat Ability Handlers
Add WCInputHandler_CombatAbility for attack inputs:
- Input Action:
IA_WC_Attack - Priority: 100 (High — combat inputs take precedence over normal)
- ActionSlotTag:
WC.Input.Action.Attack.Light— this tag is what combat styles and weapon fragments use to identify this slot - OnPressAbilityTag: Leave empty if you're using a combat style to determine the ability dynamically
- bGateOnWeaponState: true — only fires when a weapon is drawn
- bAllowAirborne: true if you want air attacks
Repeat for heavy attack, dodge, block, and any other combat inputs — each gets its own handler with its own ActionSlotTag.
- Input Action:
-
Add Menu Toggle Handler
Add WCInputHandler_MenuToggle:
- Input Action:
IA_WC_ToggleInventory - Priority: 100
- WidgetClass: Your inventory widget Blueprint (subclass of
WCActivatableWidget) - LayerTag: The UI layer to push the widget to (e.g.,
WC.UI.Layer.Menu)
- Input Action:
-
Assign Setup to Player Controller and Verify
Open
BP_WC_PlayerController. In Details, set Default Input Setup toDA_WC_Input_Default. Press Play. EnablebDebugInputBufferin Project Settings temporarily — you'll see a small on-screen overlay showing buffered inputs as you press keys. Press WASD and confirm the character moves. Press Space and confirm the character jumps.
Module: WCInteraction
WCInteraction
Layer 2 Feature — World interaction framework supporting 8 interaction types, cooperative interactions, and context-sensitive prompts.
Setting Up an Interactable Actor — Detailed Steps
-
Understand the Two-Component System
The interaction system uses exactly two components:
WCInteractionComponent— goes on the player character. It scans for nearby interactables using the configured detection mode and shows UI prompts. It is already included onAWCCharacterBase.WCInteractableComponent— goes on any world actor you want to be interactable (door, chest, NPC, lever, etc.).
-
Configure the Player's WCInteractionComponent
Open your player character Blueprint. Click the WCInteractionComponent in the Components panel. In the Details panel, configure:
Property Description Recommended Value DetectionModeHow the player detects interactables CapsuleTrace for third-person, Trace for first-person TraceLengthHow far the detection reaches 250cm (matches Project Settings default) TraceRadiusWidth of the capsule/sphere trace 50cm for CapsuleTrace MaxInteractablesHow many interactables can be detected at once 3 WidgetPoolSizeHow many interaction prompt widgets to pre-allocate 3 PromptWidgetClassThe widget Blueprint to show as the interaction prompt Your subclass of WCInteractionWidget -
Create the Interactable Actor
Create or open your world actor Blueprint (e.g.,
BP_WC_InteractChest). In the Components panel, click Add → WCInteractableComponent. Configure its properties:Property Description Example Value InteractionTypeHow the interaction is triggered. See types table below. Instantfor chestsInteractionTextThe text shown in the prompt ("Open", "Talk", "Pick Up") "Open Chest" InteractionIconOptional icon texture in the prompt Chest icon texture HoldDurationOnly for Hold type — how many seconds to hold 1.5 (irrelevant for Instant) MaxInteractorsMax simultaneous interactors (for cooperative) 1 for solo, 2+ for co-op RequiredTagsPlayer must have these tags to interact (e.g., quest started) Empty for always-available BlockedTagsIf player has these tags, interaction is blocked Empty for no restrictions bUseInteractionDataReference a WCInteractionDataasset for complex typesfalse for simple interactions -
Bind the OnInteractionCompleted Event
In the actor Blueprint's Event Graph:
- Right-click in the graph → search for "Add Event" or "Bind Event to On Interaction Completed"
- Select the
WCInteractableComponentreference → drag off it and type "On Interaction Completed" → click Bind Event - Create a custom event node (e.g., "OnChestOpened") and connect it to the binding
- In your custom event, add the logic: play animation, open the chest lid, spawn loot, play sound, etc.
TheOnInteractionCompleteddelegate passes the Interactor (the actor who triggered it) and the Slot Index (for multi-slot cooperative interactions). Use the Interactor reference to give items to the player who interacted. -
Enable Debug Visualization to Verify Detection
In Project Settings → Dynamic RPG Worlds → Interaction, check bEnableDebugVisualization. Press Play. You will see green capsule/sphere debug shapes around your detection area and red/green outlines on interactable actors (red = not in range, green = in range and interactable).
-
Test the Interaction
Walk up to your interactable actor. You should see the prompt widget appear. Press your interact key (
IA_WC_Interact). TheOnInteractionCompletedevent fires. Check the Output Log — a successful interaction logs:[WCInteraction] Interaction completed on BP_WC_InteractChest by PlayerCharacter. -
Context-Sensitive Interaction (Optional)
For interactions that change based on state (a door that shows "Open" when closed and "Close" when open):
- Set
InteractionTypeto ContextSensitive - Set
bUseInteractionDatato true - Create a
WCInteractionDataasset and assign it. In the asset, define each context with its condition tags and the text/action for that context. - The system automatically evaluates which context applies based on the player's current tags.
- Set
-
Interaction with Ability (Optional)
For interactions that trigger a GAS ability (crafting station, magic portal):
- Set
InteractionTypeto Ability - Set
InteractionAbilityTagon the component to the ability tag to activate (e.g.,WC.Ability.Interaction.Craft) - Add
WCAbilityFragment_InteractionMontageto the ability definition if you want a montage to play during interaction
- Set
Module: WCInventory
WCInventory
Layer 2 Feature — Fragment-based inventory, multi-container support, equipment with set bonuses, crafting, loot tables, jigsaw grid, currency, and world items.
Creating a Complete Weapon Item — Detailed Steps
-
Create the WCItemDefinition Asset
Right-click → Miscellaneous → Data Asset → WCItemDefinition. Name it
DA_WC_Inventory_Item_IronSwordand store inContent/WC/Inventory/Items/Weapons/. -
Set the Base Item Properties
Open the asset. Fill in the top-level properties:
- Display Name: "Iron Sword"
- Description: "A reliable iron sword. Heavy but effective."
- Icon: Assign your sword thumbnail texture
- Item Tags: Click the gameplay tag picker and add:
WC.Item.Type.WeaponandWC.Item.Type.Weapon.Sword - bCanBeDropped: true (can be dropped to the ground)
- bCanBeSold: true
-
Add WCFragment_Equippable
In the Fragments array, click + and select WCFragment_Equippable. Configure it:
Property Description Value for Iron Sword EquipmentSlotWhich slot this item goes in WC.Item.Slot.MainHandHandednessOneHanded / TwoHanded / DualWielded OneHandedRequiredLevelMinimum character level to equip 1 RequiredTagsPlayer must have these tags to equip (e.g., class/race restrictions) Empty (no restriction) GrantedAbilitiesGAS abilities granted while equipped (e.g., a block ability) Leave empty for now GrantedEffectsGAS effects applied while equipped (e.g., passive damage bonus) Leave empty for now SetTagGameplay tag identifying this item's equipment set (for set bonuses) Empty (no set) -
Add WCFragment_WeaponData
Click + in Fragments and select WCFragment_WeaponData:
Property Description Value DamageTypeTagType of damage this weapon deals WC.Combat.DamageType.Physical.SlashBaseDamageFlat base damage value before attribute scaling 25.0 TraceSocketsArray of socket name pairs for melee trace. Add each socket by name. Must exist on your weapon's skeletal mesh. "WeaponRoot", "WeaponTip" WieldedAbilitiesAbilities to grant when this weapon is drawn (not just equipped). Use for attack abilities. Your slash ability tag Finding Socket Names: Open your weapon's Skeletal Mesh in the mesh editor. Click on the Socket Manager (chain link icon in the toolbar). The list shows all sockets. Add "WeaponRoot" at the hilt and "WeaponTip" at the blade tip if they don't exist yet. -
Add WCFragment_Rarity
Click + → WCFragment_Rarity. Set RarityTag to
WC.Item.Rarity.Common. The rarity system automatically assigns the display color and any rarity-based scaling defined in yourWCRarityConfigDataAsset. -
Add WCFragment_Weight
Click + → WCFragment_Weight. Set Weight to
3.5(kilograms). If the weight system is disabled in Project Settings, this fragment is still valid but has no effect. -
Add WCFragment_EquipmentVisual
Click + → WCFragment_EquipmentVisual. Configure:
- StaticMesh or SkeletalMesh: Assign your weapon's mesh asset
- AttachSocket: The socket on the character skeleton where the weapon attaches in-hand. Common names:
hand_r,weapon_r. Check your character's skeleton socket list. - HolsterSocket: Where the weapon hangs when sheathed. Common:
spine_03or a customsword_holstersocket.
-
Add WCFragment_AttributeModifiers (Stat Bonuses)
Click + → WCFragment_AttributeModifiers. In the Modifiers array, click + and configure each bonus:
- AttributeTag:
WC.Attribute.Strength(or whichever stat this sword boosts) - Value: 5.0
- Operation:
Add(adds 5 to Strength while equipped)
Available operations:
Add(flat bonus),Multiply(percentage bonus),Override(sets the value directly). These modifiers are automatically applied as a Gameplay Effect when the item is equipped and removed when unequipped. - AttributeTag:
-
Add WCFragment_WorldRepresentation
Click + → WCFragment_WorldRepresentation. Set WorldItemClass to
AWCStandardWorldItem(or your custom subclass). Optionally assign a WorldMesh that differs from the equipped mesh (e.g., a lower-poly version for the dropped item). -
Save and Test the Item
Click Save on the asset. Press Play. Open the console (~) and type your test command to give the item to the player (e.g., a debug Blueprint node calling
WCInventoryLibrary::AddItemToInventory(PlayerCharacter, DA_WC_Inventory_Item_IronSword, 1)). Open the inventory UI and verify the sword appears. Try equipping it — the visual mesh should attach to the hand socket, and the attribute bonus should apply (verify withshowdebug abilitysystem).
Equipment System Quick Reference
| Feature | How to Set Up |
|---|---|
| Equipment Slots | Create WCEquipmentSlotDefinition assets (one per slot type) and add to Project Settings → Inventory → Equipment Slots |
| Two-Handed Weapons | Set Handedness = TwoHanded on WCFragment_Equippable — this automatically blocks the off-hand slot |
| Set Bonuses | Create WCEquipmentSetDefinition asset, define tiers (2-piece, 4-piece), assign SetTag on each item's WCFragment_Equippable |
| Dual Wield | Set Handedness = DualWielded and add WCFragment_DualWeaponVisual for the off-hand mesh |
All Item Fragment Types
| Fragment | Purpose |
|---|---|
WCFragment_Stackable | Allow stacking. Set MaxStackCount. |
WCFragment_Durability | Item wear/condition with MaxDurability and DegradationRate |
WCFragment_Equippable | Equipment slot, handedness, requirements, granted abilities/effects |
WCFragment_WeaponData | Melee weapon stats: damage type, trace sockets, wielded abilities |
WCFragment_RangedWeaponData | Ranged stats: fire mode, hit method, ammo, damage falloff, reload |
WCFragment_ArmorData | Armor value and resistance tag mappings |
WCFragment_EquipmentVisual | Mesh, attach socket, holster socket |
WCFragment_DualWeaponVisual | Off-hand mesh for dual wield items |
WCFragment_AttributeModifiers | Stat bonuses auto-applied as GE on equip |
WCFragment_Ammunition | Ammo type tag, bonus damage, impact effects, projectile class override |
WCFragment_Explosive | AoE explosion with 5 detonation modes |
WCFragment_Projectile | Projectile flight physics (collision radius, penetration, sticks-on-impact) |
WCFragment_WeaponAccuracy | Spread system: base spread, per-shot accumulation, decay rate |
WCFragment_WeaponCharge | Per-weapon charge overrides: charge time, damage/speed curves |
WCFragment_CrosshairData | Weapon-specific crosshair style (references WCCrosshairData asset) |
WCFragment_GripConfig | One/two-handed grip mode switching |
WCFragment_Container | Bag/container slots and weight limit |
WCFragment_Spatial | Jigsaw grid dimensions (width × height) for Diablo-style inventory |
WCFragment_Consumable | Use ability, applied effects, cooldown, use requirements |
WCFragment_Catalyst | Crafting tool/station catalyst type, tier, durability cost, bonuses |
WCFragment_CurrencyValue | Items that function as currency |
WCFragment_QuestItem | Quest item flags, undiscardable flag |
WCFragment_WorldRepresentation | World drop actor class and mesh |
WCFragment_CombatActions | Maps input slot tags to combat ability tags (simpler alternative to full combat styles) |
Module: WCCombat
WCCombat
Layer 2 Feature — Full melee and ranged combat system. Trace-based hit detection, projectiles, hitscan, attack chains, combo trees, combat styles, weapon wield/swap.
Setting Up a Combat Style — Detailed Steps
-
Create the WCCombatStyleDefinition Asset
Right-click → Miscellaneous → Data Asset → WCCombatStyleDefinition. Name it
DA_WC_Combat_Style_SwordAndShield. Store inContent/WC/Combat/Styles/. -
Set Identity Properties
- StyleTag:
WC.Combat.Style.SwordAndShield— unique identifier used to activate/deactivate this style - Display Name: "Sword and Shield"
- Description: "A balanced defensive style with parry and quick thrusts."
- Icon: Optional icon texture for style display in UI
- StyleTag:
-
Set Weapon Requirements
This determines when the style activates based on equipped weapons.
- WeaponRequirementMode:
PerHand— evaluates each hand independently - MainHandRequirements: Click the tag query editor. Add condition: Has Tag
WC.Item.Type.Weapon.Sword - OffHandRequirements: Add condition: Has Tag
WC.Item.Type.Weapon.Shield - StyleEvaluationMode:
Equipped— matches against equipped (not necessarily drawn) weapons. UseWieldedif you only want the style active when weapons are drawn.
- WeaponRequirementMode:
-
Map Combat Action Slots to Abilities
In the CombatActionAbilities array, add one entry per input action:
Slot Tag Ability Tag What it Does WC.Input.Action.Attack.LightWC.Ability.Combat.SwordSlashLight attack fires the slash ability WC.Input.Action.Attack.HeavyWC.Ability.Combat.ShieldBashHeavy attack fires the bash ability WC.Input.Action.BlockWC.Ability.Combat.BlockBlock input activates block ability WC.Input.Action.ParryWC.Ability.Combat.ParryParry input activates parry ability -
Configure Passive Effects (Optional)
In PassiveEffects, add any Gameplay Effects that should be active while this style is equipped. For example, a shield might grant a passive +20% block chance effect.
-
Configure Anim Layer (Optional)
If you have a different animation layer for this style (different idle pose, different movement cycle), set the AnimLayerClass to your Animation Blueprint layer subclass. The system will call
LinkAnimLayerwhen the style activates andUnlinkAnimLayerwhen it deactivates. -
Register the Style in Project Settings
Edit → Project Settings → Dynamic RPG Worlds → Combat → Registered Combat Styles. Click + and assign your new
DA_WC_Combat_Style_SwordAndShieldasset. The combat style subsystem will register it at startup.A style that is not registered in Project Settings will never activate, even if the player equips the correct weapons. Always register new styles.
Combat Animation Notifies
| Notify | Type | When to Use |
|---|---|---|
WCAnimNotifyState_MeleeTrace | State | Drag from Notify track in montage editor — frames between Begin and End are where hit detection runs |
WCAnimNotifyState_AttackChainWindow | State | Place near end of section — Begin opens the chain input window, End closes it |
WCAnimNotify_ChainTransitionPoint | Point | Frame-exact chain point — if input buffered: advance immediately. If not: opens window. |
WCAnimNotifyState_MontageSpeed | State | Dynamically changes playback speed between Begin/End frames |
WCAnimNotify_ProjectileRelease | Point | Fire the projectile at this exact frame (bow release, gun muzzle fire) |
WCAnimNotify_ReloadComplete | Point | Ammo transfer during reload. Place one per round for partial (e.g., shotgun) reloads. |
WCAnimNotify_ChargeStart | Point | Start charge tracking. Re-entry safe for looping montage sections. |
WCAnimNotify_WeaponWield | Point | Frame-exact draw/sheathe moment. Mode: Auto / AlwaysDraw / AlwaysSheathe. |
WCAnimNotify_WeaponSwap | Point | Weapon swap. Use 1–3 notifies per swap (Sheathe → Swap → Draw modes). |
Module: WCUIFramework
WCUIFramework
Layer 2 Feature — CommonUI-based HUD, activatable widget stacks, crosshair system, notifications, tooltips, themes, and MVVM base classes.
Setting Up the Crosshair — Detailed Steps
-
Create a WCCrosshairData Asset
Right-click → Miscellaneous → Data Asset → WCCrosshairData. Name it
DA_WC_UI_Crosshair_Default. This asset defines the visual appearance of the crosshair for your default weapon (or unarmed state). -
Configure Every Property
Property Description Typical Value CenterDotTextureTexture for the center dot. Leave null for no dot. Small white dot texture SpreadTextureTexture for the four cardinal spread arms Thin line texture HitMarkerTextureTexture flashed when a hit is confirmed X or V shaped texture MinSpreadOffsetDistance of spread arms from center at rest 8.0 pixels MaxSpreadOffsetMaximum spread distance (full bloom) 40.0 pixels SpreadKickAmountHow much spread increases on ShotFired event 15.0 SpreadKickRandomRangeRandomness added to each kick (visual recoil variation) 3.0 SpreadRecoveryRateHow fast spread returns to MinSpreadOffset per second 20.0 HitMarkerDurationSeconds the hit marker is visible 0.2 DefaultColorDefault crosshair color White (1,1,1,1) TargetColorOverridesTag → color mappings. Add: WC.Character.State.Enemy→ Red.WC.Character.State.Friendly→ Green.Depends on game OverallScaleGlobal scale multiplier for the entire crosshair 1.0 -
Create Your HUD Widget Blueprint
Right-click → Blueprint Class → search WCHUDWidget. Name it
WBP_WC_HUD. Open it in the Widget Blueprint editor. The parent class (WCHUDWidget) already handles crosshair spawning and lifecycle. You can add your own widgets (health bar, stamina bar, minimap) directly to this widget. -
Assign the Default Crosshair Data
In your HUD Widget Blueprint, select the
WCCrosshairWidgetchild widget. In its Details panel, assign Default Crosshair Data to yourDA_WC_UI_Crosshair_Defaultasset. -
Register the HUD Widget Class in Settings
Project Settings → Dynamic RPG Worlds → UI → Default HUD Widget Class. Set it to
WBP_WC_HUD. This tellsAWCHUDwhich widget to spawn. -
Add Weapon-Specific Crosshair Overrides
For weapons that should show a different crosshair (sniper rifle with scope dots, shotgun with wide spread): add
WCFragment_CrosshairDatato the weapon'sWCItemDefinition. Assign a differentWCCrosshairDataasset. When that weapon is equipped and drawn, its crosshair data automatically overrides the default.
Module: WCAudioSuite
WCAudioSuite
Layer 2 Feature — Tag-driven adaptive music, dynamic ambient soundscapes, stingers, and combat audio. Integrates with Dynamic Society calendar for day/night variants.
Setting Up Adaptive Music — Detailed Steps
-
Create Music Layer Definition Assets
Each music state has multiple audio layers (drums, melody, ambient texture). Create one
WCMusicLayerDefinitionper layer:Right-click → Miscellaneous → Data Asset → WCMusicLayerDefinition. Name it
DA_WC_Audio_Layer_Combat_Drums.- SoundAsset: Your MetaSound or Sound Wave asset for this layer
- DefaultVolume: 1.0
- bLooping: true (music should loop)
- FadeInDuration: 2.0 seconds
- FadeOutDuration: 1.5 seconds
-
Create Music State Definition Assets
One per musical state (Exploration, Combat, Town, Boss, Victory, etc.):
Data Asset → WCMusicStateDefinition. Name:
DA_WC_Audio_State_Combat.- StateName: "Combat"
- Layers: Add all layer definitions for this state (drums, melody, bass)
- CrossfadeDuration: 2.0 (how long to blend when transitioning to this state)
- IntroStinger: Optional one-shot sound played when this state activates (e.g., combat horn)
- OutroStinger: Optional sound played when leaving this state
-
Configure the HUD's Music Director Component
Open your
WBP_WC_HUDBlueprint (orBP_WC_HUDactor Blueprint). Select the WCMusicDirectorComponent. In the MusicStateMappings array, add one entry per state:ActivationTag MusicState Priority Notes WC.State.Gameplay.CombatDA_WC_Audio_State_Combat100 High priority — combat overrides exploration WC.State.Gameplay.ExploringDA_WC_Audio_State_Exploration10 Default exploration music The director evaluates all mappings every frame and activates the highest-priority matching state. Add as many as needed (dungeon, underwater, boss fight, etc.).
-
Set a Default Music State
On the
WCMusicDirectorComponent, set DefaultMusicState to your exploration state. This plays when no gameplay tags match any mapping. -
Place Ambient Zone Volumes
In your level, add an AWCAmbientZoneVolume actor (search in Place Actors panel). Scale it to cover your ambient area (forest, cave, town). In its Details, assign a
WCAmbientZoneDefinitionasset:- Create Data Asset → WCAmbientZoneDefinition. Name:
DA_WC_Audio_Ambient_Forest. - DaySounds: Array of ambient sounds for daytime (birds, wind, insects)
- NightSounds: Array of ambient sounds for nighttime (crickets, owls)
- BlendWeight: How strongly this zone's sounds overlay others when stacked
When the player enters the volume, its definition is pushed to the ambient stack. When they exit, it's popped. Multiple overlapping volumes stack for immersive layering.
- Create Data Asset → WCAmbientZoneDefinition. Name:
-
Set Up Combat Stingers
Create Data Asset → WCCombatAudioDefinition. In CombatStartStingers, add the sound assets to play when combat begins. In KillStingers, add sounds for kill moments. The system randomly selects from each pool for variety. Assign this asset to
WCMusicDirectorComponent → CombatAudioDefinition. -
Test the Music System
Press Play. Exploration music should start immediately. Engage in combat (the gameplay state changes to
WC.State.Gameplay.Combat). After ~2 seconds of crossfading, the combat music should be active. Kill all enemies — the state returns to Exploring and the music crossfades back. Check Output Log for:[WCMusicDirector] Requesting transition to: Combat.
Module: WCDynamicSociety
WCDynamicSociety
Layer 2 Feature — Calendar and time system, dynamic NPC social simulation, crime/justice system, factions, relationships, and regional reputation.
UCalendarSubsystem is a UGameInstanceSubsystem, NOT a World Subsystem. Access it via: GetGameInstance() → GetSubsystem (CalendarSubsystem).| System | Key Classes | Purpose |
|---|---|---|
| Calendar | UCalendarSubsystem, CalendarTypes | Configurable in-game calendar, time speed, periods, seasons |
| Social | Social Components, DynamicSocietySubsystem | NPC identity, personality, relationship tracking |
| Factions | Faction data assets, FactionSubsystem | Faction relationships, reputation tiers, rules |
| Memory | Memory system types | NPCs remember player actions, contested memories propagate |
| Crime & Justice | Crime/Guard/Witness Components, Justice Subsystem | Bounties, witness reports, guard responses, forgiveness |
| Save | FSocietySaveData, CalendarSaveTypes | Serialize the full social state |
| Async Actions | Blueprint Async Actions | Non-blocking waits for time period change, faction threshold, etc. |
See the Calendar & Factions walkthrough section for full assembly steps.
Walkthrough: Your First Melee Ability (Complete)
This walkthrough creates a 3-hit sword combo ability with attack chains, melee trace hit detection, and damage. Start to finish.
-
Create the Damage Gameplay Effect
Before creating the ability, set up the damage effect that the ability will apply:
- Right-click in Content Browser → Blueprint Class → GameplayEffect. Name it
GE_WC_Combat_MeleeDamage. - Open it. Set Duration Policy to
Instant. - In Modifiers, click +. Set:
- Attribute: Your health attribute (e.g.,
WCGASAttributePool.Attribute_00which maps to Health) - Modifier Op:
Add - Magnitude Calculation Type:
Set by Caller - Data Tag:
Data.Damage
- Attribute: Your health attribute (e.g.,
- Compile and Save. This effect subtracts the "Data.Damage" value from health when applied.
- Right-click in Content Browser → Blueprint Class → GameplayEffect. Name it
-
Create the Ability Definition
Right-click → Miscellaneous → Data Asset → WCAbilityDefinition. Name it
DA_WC_Ability_SwordSlash.Configure the top-level properties:
Property Value Why AbilityTagWC.Ability.Combat.SwordSlashUnique identifier used by combat styles and input handlers to reference this ability AbilityClassWCGameplayAbility_CombatThe base combat ability class that supports weapon requirements and combo integration InstancingPolicyInstancedPerActorEach actor gets its own ability instance, required for per-actor state tracking NetExecutionPolicyLocalPredictedClient predicts the ability for responsiveness; server validates. Use for all player combat abilities. ActivationBlockedTagsWC.State.Gameplay.DeadPrevent activating while dead CancelAbilitiesWithTagLeave empty Add tags of abilities this should cancel (e.g., cancel a block ability when attacking) CostEffectOptional — create a GE that subtracts 10 Stamina on activate Stamina cost per swing CooldownEffectOptional — create a GE with Duration for cooldown Prevents ability spam -
Prepare Your Attack Montage
Open your attack Animation Montage in the editor. If you don't have one, create one from an animation sequence: right-click the animation asset → Create Montage.
- In the montage editor, find the Sections panel at the top. Click Add Section three times: name them
Attack_01,Attack_02,Attack_03. - Drag the section markers to divide the montage into three equal-ish parts (or at natural animation breakpoints).
- In the Notifies track, right-click in the middle of each section's swing phase and select Add Notify State → WCAnimNotifyState_MeleeTrace. Drag its begin/end handles to cover the frames where the blade would cut through the air.
- Near the end of each section (with a few frames remaining), right-click and add Notify State → WCAnimNotifyState_AttackChainWindow. Start it about 0.3 seconds before the section ends and let it end at the section boundary. This defines the window where pressing attack again will chain to the next section.
- In the montage editor, find the Sections panel at the top. Click Add Section three times: name them
-
Add WCAbilityFragment_MeleeCombat
Back in
DA_WC_Ability_SwordSlash, in the Fragments array, click + and select WCAbilityFragment_MeleeCombat. Configure every property:Property Value Explanation AttackMontageYour attack montage The montage that plays when this ability activates AttackSourceWeaponUse weapon trace sockets for hit detection. Set to Unarmed for fist-based attacks. WeaponHandMainHandUse the main hand weapon's trace sockets bUseAttackChaintrue Enable the 3-hit chain system bLoopAttackChainfalse Do not loop back to Attack_01 after Attack_03 — end the chain ChainWindowDuration0.0 We're using AnimNotifyState for window control, so set this to 0 to disable timer-based window ChainComboTimeout1.5 If no next input arrives within 1.5 seconds after chain ends, reset the chain AttackChainSectionsAdd 3 entries See below for each section DamageEffectGE_WC_Combat_MeleeDamageThe damage GE to apply on hit BaseDamageValue25.0 The SetByCaller Data.Damage value passed to the GE AttackChainSections — add 3 rows:
SectionName DamageMultiplier AttackSource WeaponHand SectionStartOffset Attack_011.0 Weapon MainHand 0.0 Attack_021.15 Weapon MainHand 0.05 Attack_031.8 Weapon MainHand 0.0 SectionStartOffseton Attack_02 (0.05 = 50ms) skips the windup when chaining INTO this section mid-combo for snappier feel. Attack_03 is the finisher — no skip needed since players have had time to commit. -
Configure Trace Settings in Project Settings
Project Settings → Dynamic RPG Worlds → Combat:
- TraceMode:
MultiPointSweep— traces between previous and current socket positions every physics tick during the trace window. Best for fast swings. - TraceRadius: 15.0cm
- TraceChannel:
ECC_Pawn(or create a custom "WeaponTrace" channel in Project Settings → Collision) - bDebugTraces: true for now — disable before shipping
- TraceMode:
-
Grant the Ability to the Character
Choose one of two methods:
Method A — Via Weapon Equipment (Recommended): In your sword item's
WCFragment_Equippable, add the ability tag to GrantedAbilities. The ability is automatically granted when the sword is equipped and revoked when unequipped.Method B — Via StartingAbilitiesData (Always Active): Create Data Asset → WCStartingAbilitiesData. Add
WC.Ability.Combat.SwordSlashto the abilities list. On your character'sWCGASAttributeInitializercomponent, set this asset as StartingAbilities. The ability is granted at BeginPlay. -
Wire Input to the Ability
If using a combat style (recommended), the style's
CombatActionAbilitiesmapsWC.Input.Action.Attack.Light→WC.Ability.Combat.SwordSlash. TheWCInputHandler_CombatAbilitywithActionSlotTag = WC.Input.Action.Attack.Lightthen resolves the ability from the active style and activates it.If NOT using a combat style, on the
WCInputHandler_CombatAbility, set OnPressAbilityTag directly toWC.Ability.Combat.SwordSlash. -
Test With AWCDummy
Place an
AWCDummyactor in your level. Press Play. Equip your sword. Walk up to the dummy. Press Attack. You should see:- The attack montage plays (Attack_01 section)
- Red debug spheres appear along the blade during the trace window (if
bDebugTracesis on) - The Output Log shows:
[WCMeleeTrace] Hit: AWCDummy | Damage: 25.0 | Surface: Physical - Press Attack again quickly (during chain window) — the montage jumps to Attack_02
- Press again — Attack_03 fires (with 1.8× damage multiplier)
If nothing happens: verify the ability was granted (
showdebug abilitysystemshould list it), and confirm the melee trace notify exists in the montage.
Walkthrough: Your First Ranged Weapon (Complete)
End-to-end setup of a bow with arrow ammo, aim-down-sights, and reload mechanics.
-
Create the Arrow Ammo Item Definition
Data Asset → WCItemDefinition. Name:
DA_WC_Item_Arrow_Steel. Add these fragments:- WCFragment_Stackable: MaxStackCount = 99
- WCFragment_Rarity: RarityTag =
WC.Item.Rarity.Common - WCFragment_Ammunition:
- AmmoTypeTag:
WC.Combat.Ammo.Type.Arrow - BonusDamage: 0 (base arrows add no bonus)
- ProjectileClass:
AWCProjectileWorldItem(or your custom projectile) - RecoveryChance: 0.5 — 50% chance to recover the arrow after it lands
- AmmoTypeTag:
-
Create the Bow Item Definition
Data Asset → WCItemDefinition. Name:
DA_WC_Item_Bow_Wood. Add fragments:- WCFragment_Equippable: Slot =
WC.Item.Slot.MainHand, Handedness =TwoHanded - WCFragment_RangedWeaponData:
- RangedHitMethod:
Projectile - FireMode:
Single(one shot per press — required for attack chains with bows) - AmmoTypeTag:
WC.Combat.Ammo.Type.Arrow— matches the arrow's AmmoTypeTag - AmmoConsumption:
DirectPerShot— consumes one arrow from inventory per shot - AmmoLocation:
Inventory— draws from the player's main inventory - ProjectileSpeed: 3000.0 cm/s
- ProjectileGravityScale: 0.3 (slight arc for arrows)
- DamageFalloffCurve: Optional curve asset — damage at full range
- RangedHitMethod:
- WCFragment_WeaponAccuracy: BaseSpread = 1.0, SpreadPerShot = 2.0, DecayRate = 8.0 (spread recovers quickly for bows)
- WCFragment_EquipmentVisual: Assign bow mesh, attach socket, holster socket
- WCFragment_CrosshairData: Assign a crosshair data asset suited for bows (dot-only, no spread arms)
- WCFragment_CombatActions: Map
WC.Input.Action.Attack.Light→WC.Ability.Combat.BowShot
- WCFragment_Equippable: Slot =
-
Create the Bow Shot Ability Definition
Data Asset → WCAbilityDefinition. Name:
DA_WC_Ability_BowShot. Set AbilityTag =WC.Ability.Combat.BowShot, AbilityClass =WCGameplayAbility_Combat, NetExecutionPolicy =LocalPredicted.Add WCAbilityFragment_RangedCombat:
Property Value AttackMontageYour bow shoot montage AttackSourceWeapon WeaponHandMainHand RangedHitMethodProjectile FireModeSingle BaseDamageValue40.0 DamageEffectGE_WC_Combat_RangedDamage In the montage, place WCAnimNotify_ProjectileRelease at the frame where the arrow leaves the bow (when the hand releases). This is what actually fires the projectile.
-
Add Aim-Down-Sights (Optional)
Create Data Asset → WCAbilityDefinition named
DA_WC_Ability_BowAim. Add WCAbilityFragment_Aim:- AimBehavior:
HoldToAim— hold the aim input, release to return to normal - AimRotationMode:
OrientToCamera— character rotates to face camera direction while aiming - FOVMultiplier: 0.65 — reduces FOV to 65% for zoom effect
- MovementSpeedMultiplier: 0.5 — slow movement while aiming
Add this ability to the bow's
WCFragment_Equippable → GrantedAbilities. WireIA_WC_HeavyAttackto anWCInputHandler_CombatAbilitywithActionSlotTag = WC.Input.Action.Aim. - AimBehavior:
-
Add Charge Attack for Bow (Optional)
Add WCAbilityFragment_ChargeAttack to the BowShot ability definition:
- ChargeTime: 1.5 seconds (time to reach full charge)
- MinChargeRatio: 0.3 — must charge at least 30% before a valid release
- ChargeDamageCurve: Create a float curve: at ratio 0.0 → multiplier 0.5, at ratio 1.0 → multiplier 2.0
- ChargeSpeedCurve: Create a float curve for projectile speed scaling
In the bow draw montage, place WCAnimNotify_ChargeStart at the frame when the bowstring is drawn. Charge tracking begins at this frame.
-
Test the Bow
Equip the bow. The character should wield it (if you set up a WieldAbility). Press Attack — the draw-and-shoot montage plays, a projectile spawns at the muzzle, and it arcs toward where you're aiming. Check Output Log for:
[WCRangedCombat] Projectile fired | Velocity: 3000 | Gravity: 0.3. If the projectile doesn't spawn, verify theWCAnimNotify_ProjectileReleaseexists in the montage at the correct frame.
Walkthrough: Setting Up a Tree-Based Combo
Tree combos detect multi-input sequences (like quarter-circle combos in fighting games) and fire special abilities when the full sequence is entered.
-
Understand the Combo System
The tree works like this: each node in the tree has incoming input conditions and an ability to fire. The player starts at the root and navigates deeper with each input. When a terminal node (no outgoing branches) is reached, the combo completes.
Two modes:
- FightingCombo: Only the final node fires an ability. The sequence is a "password" for a powerful move.
- ComplexCombo: Every node fires its own ability. Each step triggers something (action RPG style).
-
Create the WCComboDefinition Asset
Right-click → Miscellaneous → Data Asset → WCComboDefinition. Name it
DA_WC_Combo_SpinningStrike. -
Configure the Combo Identity
- ComboTag:
WC.Combat.Combo.SpinningStrike - ComboMode:
FightingCombo— only the finisher fires - DefaultMaxStepInterval: 0.5 — player has 0.5 seconds between inputs by default
- MaxTotalDuration: 3.0 — combo resets if not completed within 3 seconds total
- Priority: 100 — higher priority combos are checked first
- RequiredTags: Empty (available in any state)
- BlockedTags:
WC.State.Gameplay.Dead - CompletionAbilityTag:
WC.Ability.Combat.SpinningStrike— ability that fires when the combo completes
- ComboTag:
-
Define the Combo Tree Nodes
Our combo is: Light → Light → Heavy (three inputs). Add nodes to the Nodes array:
Index NodeName AbilityTag MaxTimeToReach Notes 0 "First Light" Empty (FightingCombo — no intermediate ability) 0 (use default) Reached after first Light input 1 "Second Light" Empty 0 Reached after second Light input 2 "Spinning Strike Finisher" WC.Ability.Combat.SpinningStrike0 Terminal node — fires the finisher ability -
Define the Root Transitions and Node Transitions
In RootTransitions, add one entry:
- InputTag:
WC.Input.Action.Attack.Light - NextNodeIndex: 0
On Node 0, in its Transitions array, add:
- InputTag:
WC.Input.Action.Attack.Light→ NextNodeIndex: 1
On Node 1, in its Transitions array, add:
- InputTag:
WC.Input.Action.Attack.Heavy→ NextNodeIndex: 2
Node 2 has no transitions — it's a terminal node, so reaching it completes the combo.
- InputTag:
-
Add WCInputHandler_ComboInput to Your InputSetupData
Open
DA_WC_Input_Default. In Handlers, add WCInputHandler_ComboInput:- Priority: 100 (above normal, same as combat)
- ComboDefinitions: Add
DA_WC_Combo_SpinningStrike - FallbackAbilityTag:
WC.Ability.Combat.SwordSlash— fires if no combo matches the input - bRouteToActiveAbilityOnNoMatch: true — routes to the active ability for attack chain advancement when no combo matches
- InputAction:
IA_WC_Attack(the handler listens to this action for combo inputs)
-
Create the Spinning Strike Ability
Create
DA_WC_Ability_SpinningStrike(WCAbilityDefinition). AddWCAbilityFragment_MeleeCombatwith a special spinning montage and higher damage values. Grant this ability viaWCStartingAbilitiesDataor the equipped weapon. -
Test the Combo
Press Play. Press Light → Light → Heavy within 0.5 seconds between each input. You should see the Spinning Strike ability activate on the third input. Try pressing Light → Light → Light (wrong third input) — the combo should drop and fall back to the normal slash. Enable
bDebugInputBufferin Project Settings to see the combo tree navigation in the Output Log.
Walkthrough: Building a Loot Table
-
Create Item Definition Assets First
Loot tables reference item definitions. Make sure you have at least 3–5 item definitions created (swords, potions, gold coins, etc.) following the item creation steps in the WCInventory module section.
-
Create the WCLootTableDefinition Asset
Right-click → Miscellaneous → Data Asset → WCLootTableDefinition. Name it
DA_WC_Loot_BanditChest. -
Configure the Loot Table Properties
- MinDrops: 2 — minimum number of items guaranteed to drop
- MaxDrops: 4 — maximum number of items (randomized between min and max)
- bGuaranteeMinDrops: true — always generate at least MinDrops even if RNG is unlucky
-
Add Loot Entries
In the Entries array, click + for each possible drop. Each entry has:
Property Description Example: Gold Coins EntryTypeItem, NestedTable, or Nothing Item ItemDefinitionThe item to drop (only for Item type) DA_WC_Item_GoldCoinWeightRelative probability (higher = more common). Not a percentage — it's relative to the sum of all weights. 100 (very common) MinQuantityMinimum stack size for this drop 5 MaxQuantityMaximum stack size for this drop 25 bAlwaysDropThis entry always drops regardless of roll (guaranteed drop) false RequiredContextTagsFWCLootContext must have these tags for this entry to be eligible Empty (always eligible) Add entries for: Gold Coins (weight 100, qty 5–25), Iron Sword (weight 30, qty 1), Health Potion (weight 50, qty 1–2), Rare Sword (weight 5, qty 1).
-
Add a Nested Table (Optional)
For more variety, add an entry with
EntryType = NestedTableand reference another loot table. When the RNG selects this entry, it rolls the nested table to determine the actual drop. Useful for: "10% chance to roll the 'rare weapons' table". -
Call GenerateLoot from Blueprint
On your chest actor's
OnInteractionCompletedevent:- Get the
WCInventoryLibrarynode Generate Loot - Connect your
DA_WC_Loot_BanditChestas the Loot Table input - Create a
FWCLootContextstruct: set CharacterLevel (from interactor), LuckFactor (from character's Luck attribute), ContextTags (optional filter tags) - The node returns an array of
FWCLootEntry(item definition + quantity)
- Get the
-
Spawn World Items from Loot Results
For each entry in the loot array, you have two choices:
- Give to Player Directly: Call
WCInventoryLibrary::AddItemToInventory(Interactor, LootEntry.ItemDef, LootEntry.Quantity) - Spawn as World Item: Call
SpawnActor → AWCStandardWorldItemnear the chest location, then callWorldItem::Initialize(LootEntry.ItemDef, LootEntry.Quantity)
A common pattern: give small items (coins, potions) directly to inventory, and spawn world items for weapons and armor so the player can choose what to pick up.
- Give to Player Directly: Call
Walkthrough: Crafting System — Recipe to Workbench
-
Create Ingredient Item Definitions
Craft inputs are item definitions. Create simpler items for ingredients:
DA_WC_Item_IronIngot,DA_WC_Item_WoodPlank. These only need minimal fragments:WCFragment_StackableandWCFragment_Rarity. -
Create the Recipe Category
Data Asset → WCRecipeCategoryDefinition. Name:
DA_WC_Recipe_Category_Blacksmithing.- DisplayName: "Blacksmithing"
- Icon: Anvil icon texture
- CategoryTag:
WC.Crafting.Category.Blacksmithing
-
Create the Recipe Definition
Data Asset → WCRecipeDefinition. Name:
DA_WC_Recipe_IronSword.Property Value RecipeName"Iron Sword" CategoryDA_WC_Recipe_Category_BlacksmithingRequiredStationTagWC.Crafting.Station.ForgeCraftingTime3.0 seconds bRequiresCatalystfalse (no catalyst needed for basic recipe) In Inputs, add:
- Entry 1:
DA_WC_Item_IronIngot, Quantity: 3 - Entry 2:
DA_WC_Item_WoodPlank, Quantity: 1
In Outputs, add:
- Entry 1:
DA_WC_Item_IronSword, Quantity: 1
- Entry 1:
-
Create the Crafting Station World Actor
Create or open your Forge Blueprint (e.g.,
BP_WC_Forge). Add two components:- WCInteractableComponent: Type =
Ability, InteractionText = "Craft", InteractionAbilityTag =WC.Ability.Interaction.OpenForge - WCCraftingStationComponent:
- StationTypeTag:
WC.Crafting.Station.Forge— this must match theRequiredStationTagin your recipes - AvailableRecipes: Add
DA_WC_Recipe_IronSword(and any other recipes this station supports)
- StationTypeTag:
- WCInteractableComponent: Type =
-
Open the Crafting UI on Interaction
Create an ability
DA_WC_Ability_OpenForge. Add a Blueprint ability fragment that callsWCUIManagerSubsystem::PushWidget(CraftingWidgetClass, GameMenuLayer)passing yourWBP_WC_Craftingwidget. The widget's view model (WCCraftingVM) auto-binds to the nearby crafting station when pushed. -
Verify the Crafting Flow
Press Play. Add 3 Iron Ingots and 1 Wood Plank to your inventory (use debug console). Walk to the Forge. Interact. The crafting UI should open showing the Iron Sword recipe. The ingredients should be highlighted as "available". Click Craft. After 3 seconds, the Iron Sword should appear in your inventory and the ingredients removed.
Walkthrough: Heritage — Setting Up Race and Class
-
Create a Race Data Asset
Data Asset → WCGASRaceData. Name:
DA_WC_Heritage_Race_Human.Property Value RaceName"Human" RaceTagWC.Heritage.Race.HumanDescription"Adaptable and resourceful." IconHuman portrait texture RacialTagsTags granted at character creation: WC.Heritage.Trait.AdaptiveStartingAbilitiesOptional — abilities every Human starts with AttributeModifiersFlat bonuses: Strength +2, Agility +2, Intelligence +1 ValidClassesEmpty = all classes allowed. Add class tags to restrict (e.g., Elves can't be Warriors). -
Create a Class Data Asset
Data Asset → WCGASClassData. Name:
DA_WC_Heritage_Class_Warrior.- ClassName: "Warrior"
- ClassTag:
WC.Heritage.Class.Warrior - StartingAbilities: Melee combat ability tags specific to warriors
- AttributeModifiers: Strength +5, Constitution +3 — applies on top of racial bonuses
- ClassTraits: Tags that define class identity:
WC.Heritage.Trait.MeleeSpecialist
-
Create a Subrace (Optional)
Data Asset → WCGASSubraceData. For example,
DA_WC_Heritage_Subrace_HighlanderHuman. A subrace modifies the parent race with additional attributes and traits. Assign to WCGASRaceData → Subraces array. -
Apply Heritage at Character Initialization
In your character Blueprint's BeginPlay (or a Character Creation system):
- Get the
WCGASHeritageSubsystem: GetGameInstance → GetSubsystem (WCGASHeritageSubsystem) - Call ApplyHeritage(TargetActor, RaceData, ClassData, SubraceData)
- This applies all attribute modifiers, grants starting abilities, and adds all heritage tags to the actor's ASC
- Get the
-
Verify Heritage Application
Press Play. Use
showdebug abilitysystem. Under Gameplay Tags you should see the racial and class tags (WC.Heritage.Race.Human,WC.Heritage.Class.Warrior, etc.). Under Attributes, verify the starting attribute values include the racial and class bonuses on top of the base values.
Walkthrough: Skill Tree — From Zero to Unlockable Nodes
-
Design Your Skill Tree Structure
Before creating assets, sketch your tree on paper. Decide: How many tiers? Which nodes are prerequisites for which? What abilities does each node grant? Common structure: Tier 1 has 3 nodes (starter), Tier 2 has 6 nodes (intermediate), Tier 3 has 3 powerful nodes (advanced).
-
Create the WCGASSkillTreeData Asset
Data Asset → WCGASSkillTreeData. Name:
DA_WC_SkillTree_Warrior.- TreeName: "Warrior Skills"
- TreeTag:
WC.SkillTree.Warrior - MaxTier: 3
-
Add Skill Nodes
In the Nodes array, add one entry per skill. Each node:
Property Description Example Node NodeNameDisplay name "Power Strike" NodeTagUnique identifier for this node WC.SkillTree.Warrior.PowerStrikeTierWhich tier (1 = starter) 1 PointCostSkill points to unlock 1 PrerequisitesArray of node tags that must be unlocked first Empty (Tier 1 node, no prerequisite) AbilityToGrantAbility tag granted when this node is unlocked WC.Ability.Combat.PowerStrikeEffectToApplyOptional permanent GE applied on unlock (e.g., +10 max health permanently) — DescriptionTooltip shown in UI "A powerful overhead strike dealing 200% damage." IconNode icon texture Sword icon -
Unlock a Node from Blueprint
When the player clicks a node in the skill tree UI:
- Get the
WCGASAllySubsystemor directly call the unlocking function - Call UnlockSkillNode(Actor, SkillTreeData, NodeTag)
- The system validates: are prerequisites met? Does the player have enough skill points? If valid, it grants the ability, applies any effects, and deducts skill points.
- Bind to OnSkillNodeUnlocked delegate to update the UI
- Get the
-
Show Unlock State in UI
In your skill tree widget Blueprint:
- For each node button, call IsSkillNodeUnlocked(Actor, NodeTag) → set button appearance (unlocked = bright/filled, locked = dark/grayed)
- Call CanUnlockSkillNode(Actor, SkillTreeData, NodeTag) → if prerequisites are met and the player has points, highlight the button as "available to unlock"
- Show GetSkillPoints(Actor) as the available points counter
-
Grant Skill Points on Level Up
Bind to the
WCGASLevelingSubsystem::OnLevelUpdelegate. On each level-up event, call AddSkillPoints(Actor, Amount) (typically 1–3 per level, depending on your design).
Walkthrough: Dynamic Society — Calendar and Factions
-
Configure the Calendar System
In Project Settings → Dynamic RPG Worlds → Dynamic Society → Calendar:
- DayNames: Array of strings for your world's days (e.g., ["Solday", "Moonday", "Fireday", "Waterday", "Earthday", "Windday", "Starday"])
- MonthNames: Array of your world's months with day counts per month
- SecondsPerGameHour: How many real seconds = 1 in-game hour. 60 = 1 minute of real time per game hour (24 min for a full day). 6 = very fast days.
- StartingHour: What time the game begins (e.g., 8 = 8 AM)
- StartingDay, Month, Year: Your world's starting date
-
Access the Calendar in Blueprint
The calendar is a Game Instance Subsystem (not a World Subsystem):
// Blueprint: Get Game Instance → Get Subsystem (class = CalendarSubsystem) CalendarSubsystem → GetCurrentHour() // Returns 0-23 CalendarSubsystem → GetCurrentDay() // Returns day of week CalendarSubsystem → GetCurrentMonth() // Returns month index CalendarSubsystem → GetTimePeriod() // Returns enum: Morning/Day/Evening/Night -
Bind to Time Events
In your Level Blueprint or a persistent manager actor, bind to calendar events:
- OnTimePeriodChanged: Fires when Morning/Day/Evening/Night transitions. Use to switch ambient audio, NPC behaviors, lighting.
- OnNewDay: Fires at midnight. Use for daily resets, shop restocks, schedule changes.
- OnSeasonChanged: Fires when the season changes. Use for weather changes, seasonal events.
-
Create Faction Data Assets
Data Asset → WCFactionData (or equivalent in WCDynamicSociety). Create one per faction in your world:
- FactionName: "The Merchants Guild"
- FactionTag:
WC.Society.Faction.MerchantsGuild - InitialReputation: 0 (neutral)
- ReputationTiers: Define thresholds for ranks: -100 = Enemy, -50 = Hostile, 0 = Neutral, 50 = Friendly, 100 = Honored, 200 = Exalted
- FactionRelationships: Faction-to-faction relationships (e.g., MerchantsGuild dislikes Thieves, FactionRelationValue = -50)
-
Add a Social Component to NPCs
On your NPC Blueprint, add the WCDynamicSociety social component (e.g.,
WCSocialComponentorWCNPCDataComponent). Configure:- FactionMembership: Which factions this NPC belongs to
- PersonalityTraits: Tags describing personality (aggressive, cowardly, friendly)
- ScheduleData: Optional reference to a schedule defining the NPC's daily routine
-
Modify Player Reputation
When the player completes quests, makes purchases, or commits crimes:
// Blueprint: Get Dynamic Society Subsystem → Modify Reputation DynamicSocietySubsystem → ModifyPlayerReputation( PlayerActor, FactionTag, Amount, // Positive = gain, negative = lose bPropagate // Propagate to allied/enemy factions automatically ) -
Use Async Actions for Waiting
In Blueprints that need to wait for a society event without blocking:
- Use WaitForTimePeriod (Async) — fires when the specified time period (Night, Morning, etc.) begins. Useful for quests that require "come back at night".
- Use WaitForReputationThreshold (Async) — fires when player reputation with a faction crosses a threshold. Useful for unlocking quests dynamically.
End-to-End Test Checklist
Use this checklist to verify your entire WC RPG World framework is assembled correctly. Tick each item after confirming it works in Play mode.
Deep Dive: GAS and Attributes
How the Attribute Pool Works
At startup, WCGASAttributeRegistry loads all WCGASAttributeDefinition assets registered in Project Settings. Each definition is assigned a numbered pool slot (Health → slot 0, Stamina → slot 1, etc.). When an actor is initialized, its WCGASAttributeInitializer creates a WCGASAttributePool AttributeSet containing all 150 pre-generated attributes and grants it to the ASC — giving that actor all attributes, initialized from BaseValue. Unused slots cost nothing in gameplay.
Reading and Modifying Attributes
// C++: Read attribute value
float Health = WCGASAttributePoolHelper::GetAttributeValue(ASC, WCTags::Attribute_Health);
// C++: Bind to value changes
WCGASAttributePoolHelper::BindValueChangedDelegate(ASC, WCTags::Attribute_Health, [](float OldVal, float NewVal){
// React to health change
});
// Blueprint: Use the "Get Attribute Value" node from WCGASAttributePoolHelper
// Pass the ASC and the attribute tag, returns current value as float
Creating Gameplay Effects That Modify Attributes
To apply damage or healing via GAS effects:
- Create a Blueprint subclass of
UGameplayEffect - Set Duration Policy:
Instantfor one-time changes,Infinitefor permanent buffs,HasDurationfor timed effects - In Modifiers, add an entry for each attribute to modify. For damage: attribute = Health, Op = Add, Magnitude = SetByCaller with tag
Data.Damage - Apply the effect via:
ASC → ApplyGameplayEffectToTarget(GEClass, TargetASC, Level)
Deep Dive: Ability Fragment System
How Fragments Work
A WCAbilityDefinition holds an array of WCAbilityFragment objects. Each fragment can have RequiredTags/BlockedTags — conditions that gate whether the fragment executes for a given actor. When an ability activates, each fragment's lifecycle hooks fire in array order. Fragments are shared objects (not per-actor), so mutable state must be stored via the ability instance's fragment state storage.
Fragment Lifecycle Hooks
| Hook | When Called |
|---|---|
OnAbilityGranted | When the ability is granted to an ASC (setup, bind events) |
OnAbilityRemoved | When the ability is removed (cleanup) |
CanActivateAbility | Additional activation condition check — return false to block activation |
OnAbilityActivated | Main logic — called when the ability starts executing |
OnAbilityEnded | Cleanup — called when the ability ends (naturally or cancelled) |
OnAbilityInputPressed | Called when the ability's input is pressed while active (useful for hold mechanics) |
OnAbilityInputReleased | Called when input is released while active (trigger release-to-fire) |
OnAbilityTick | Periodic tick while active. Enable by setting bWantsAbilityTick = true. |
Creating a Custom Blueprint Fragment
-
Create the Fragment Blueprint
Right-click → Blueprint Class → WCAbilityFragment. Name it following the pattern:
ABF_WC_[Name](e.g.,ABF_WC_PlaySoundOnActivate). Store inContent/WC/GAS/Fragments/. -
Override OnAbilityActivated
In the Event Graph, right-click → Add Event → Event On Ability Activated. The event has an Ability output parameter (the
WCGameplayAbilityinstance). Use this to access the owning actor, the ASC, montage playback, etc.Example — play a sound on activate: drag from Ability → Get Avatar Actor → Spawn Sound Attached with your sound asset.
-
Set Activation Conditions (Optional)
In the Blueprint's default values (open the Blueprint, click the CDO in the Details panel), set Required Tags and Blocked Tags. Example: RequiredTags =
WC.Combat.State.Armed.Rangedmeans this fragment only executes when a ranged weapon is drawn. -
Add to an Ability Definition
Open any
WCAbilityDefinitionasset. In Fragments, click + and select your new fragment class from the dropdown. Configure its properties in the expanded inline editor.
Fragment Runtime State (C++ Only)
For fragments that need to store per-activation data, use the ability's fragment state map:
// Define a state struct (in your Fragment's header)
USTRUCT() struct FMyFragmentState { GENERATED_BODY()
float ElapsedTime = 0.f;
bool bIsActive = false;
};
// Read/write in fragment hooks:
FMyFragmentState& State = Ability->GetOrCreateFragmentState<FMyFragmentState>();
State.ElapsedTime += DeltaTime;
// Check if state exists:
if (Ability->HasFragmentState<FMyFragmentState>()) { ... }
// Clear state (e.g., on ability end):
Ability->ClearFragmentState<FMyFragmentState>();
Deep Dive: Item Fragment System
Creating a Custom Item Fragment
-
Create a C++ Subclass of UWCItemFragment
UCLASS(DefaultToInstanced, EditInlineNew, BlueprintType) class UMyMagicFragment : public UWCItemFragment { GENERATED_BODY() public: UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Magic") float MagicPower = 0.f; UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Magic") FGameplayTag MagicSchoolTag; };Add it to your module's Build.cs public includes. Compile.
-
Add to Item Definitions
Open any
WCItemDefinition. In Fragments, click + and selectUMyMagicFragment. Set MagicPower and MagicSchoolTag. Save. -
Access at Runtime (C++)
// From item instance: if (UMyMagicFragment* MagicFrag = ItemInstance->GetItemDefinition()->FindFragment<UMyMagicFragment>()) { float Power = MagicFrag->MagicPower; } -
Access at Runtime (Blueprint)
In Blueprint, call
WCInventoryLibrary → FindFragmentOfClass(ItemInstance, FragmentClass). Cast the result to your fragment class and access the properties.
Class Reference
DynamicRPGWorlds Module
| Class | Type | Description |
|---|---|---|
AWCGameModeBase | GameMode | Default WC game mode with class assignments |
AWCGameStateBase | GameState | Replicated game-wide state |
UWCGameInstance | GameInstance | Persistent instance with level transition hooks |
AWCPlayerController | PlayerController | Input manager + UI stubs |
AWCPlayerState | PlayerState | Server state: ASC, inventory, crafting |
AWCHUD | HUD | HUD widget spawning + crosshair + audio director |
AWCPlayerCameraManager | CameraManager | Custom camera manager (UE 5.7 fix) |
AWCCharacterBase | Character (Abstract) | Base character with state machine and GAS |
AWCPlayerCharacter | Character | Player character with data-driven camera |
AWCAICharacter | Character | AI character with own ASC |
UWCCharacterMovementComponent | Component | Extended movement with locomotion states |
UWCCameraDirector | Component | Tag-driven camera rig selection |
UWCAbilityFragment_Locomotion | Fragment | Ability-driven locomotion (sprint, crouch) |
UWCCoreLibrary | Library | Core utility Blueprint functions |
AWCDummy | Actor | Debug target for testing combat |
WCGASCore Module
| Class | Type | Description |
|---|---|---|
UWCAbilitySystemComponent | ASC | Extended GAS Ability System Component |
UWCGameplayAbility | Ability | Base ability with fragment support |
UWCAbilityDefinition | Data Asset | Complete ability definition |
UWCAbilityFragment | Fragment (Abstract) | Composable ability behavior module |
UWCStartingAbilitiesData | Data Asset | Abilities to grant at initialization |
UWCGASAttributePool | AttributeSet | 150 pre-generated replicated attributes |
UWCGASAttributeDefinition | Data Asset | Individual attribute definition |
UWCGASAttributeRegistry | GameInstance Subsystem | Maps definitions to pool slots |
UWCGASAttributeInitializer | Component | Auto-creates attribute pool on actors |
UWCGASAttributePoolHelper | Static Utility | Attribute read/write and event delegates |
UWCGASAbilityBook | Data Asset | Ability collection (spellbook, skill category) |
UWCGASAbilityLibrarySub | GameInstance Subsystem | Global ability catalog manager |
UWCGASAbilityLibFuncLib | Library | 20+ ability query/filter/sort functions |
WCCombat Module
| Class | Type | Description |
|---|---|---|
UWCCombatAbilitySystemComponent | ASC | Combat-extended ASC with style/combo management |
UWCGameplayAbility_Combat | Ability | Base combat ability class |
UWCCombatStyleDefinition | Data Asset | Complete combat style with weapon requirements |
UWCComboDefinition | Data Asset | Tree-based combo pattern |
UWCCombatStyleSubsystem | World Subsystem | Style registration and matching |
UWCAbilityTask_MeleeTrace | AbilityTask | Socket-based hit detection during attacks |
UWCAbilityFragment_MeleeCombat | Fragment | Melee attacks with chains and dual-wield |
UWCAbilityFragment_RangedCombat | Fragment | Ranged attacks with fire modes and ammo |
UWCAbilityFragment_Aim | Fragment | Aim-down-sights |
UWCAbilityFragment_Reload | Fragment | Weapon reload |
UWCAbilityFragment_ChargeAttack | Fragment | Charge-to-fire mechanics |
UWCAbilityFragment_WeaponWield | Fragment | Draw/sheathe animations |
UWCAbilityFragment_WeaponSwap | Fragment | Weapon swapping |
AWCProjectileWorldItem | Actor | Physical projectile in flight |
UWCFragment_CombatActions | Item Fragment | Maps input slots to combat abilities on items |
Tag Reference
| Tag | Description |
|---|---|
WC.Character.State.Dead | Character is dead — blocks most abilities |
WC.Character.State.Incapacitated | Alive but stunned/unable to act |
WC.Character.Movement.Sprinting | Character is sprinting |
WC.Character.Movement.Crouching | Character is crouching |
WC.Character.Movement.Airborne | Character is in the air |
WC.Combat.State.InCombat | Actor is in active combat |
WC.Combat.State.Attacking | Actor is performing an attack |
WC.Combat.State.Blocking | Actor is blocking |
WC.Combat.State.Dodging | Actor is dodging |
WC.Combat.State.Aiming | Actor is aiming (triggers crosshair) |
WC.Combat.State.Reloading | Actor is reloading |
WC.Combat.State.Armed.Ranged | Ranged weapon is drawn (shows crosshair) |
WC.Combat.State.Armed.Melee | Melee weapon is drawn |
WC.Combat.Combo.Window_Open | Combo input window is currently open |
WC.State.Gameplay.Exploring | Player is exploring (mutually exclusive with others) |
WC.State.Gameplay.Combat | Player is in combat |
WC.State.Gameplay.Dead | Player is dead |
WC.State.Gameplay.Cinematic | Cutscene active, input disabled |
WC.Combat.Event.HitConfirmed | GAS event fired when a hit registers on a target |
WC.Combat.Event.ShotFired | GAS event fired when a ranged shot is fired |
WC.Item.Type.Weapon | Item is a weapon |
WC.Item.Type.Weapon.Sword | Item is specifically a sword |
WC.Item.Rarity.Common | Common rarity tier |
WC.Item.Rarity.Legendary | Legendary rarity tier |
WC.Item.Slot.MainHand | Main hand equipment slot |
WC.Item.Slot.OffHand | Off hand equipment slot |
Blueprint API Quick Reference
WCInventoryLibrary
| Function | Description |
|---|---|
AddItemToInventory(Actor, ItemDef, Count) | Give an item to an actor's inventory |
RemoveItemFromInventory(Actor, Instance, Count) | Remove a stack from inventory |
GetAllItems(Actor) | Get all item instances in inventory |
FindItemsByTag(Actor, Tag) | Find items matching a gameplay tag |
GetEquippedItem(Actor, SlotTag) | Get item in a specific equipment slot |
EquipItem(Actor, Instance, SlotTag) | Equip item to a specific slot |
UnequipItem(Actor, SlotTag) | Unequip from slot |
GetCurrencyAmount(Actor, CurrencyTag) | Get actor's balance for a currency |
GenerateLoot(LootTable, Context) | Roll a loot table and return results |
FindFragmentOfClass(Instance, FragClass) | Get a specific fragment from an item instance |
WCInteractionLibrary
| Function | Description |
|---|---|
GetNearestInteractable(Actor) | Find the closest interactable component |
CanInteract(Actor, Interactable) | Check if actor meets interaction conditions |
StartInteraction(Actor, Interactable) | Begin interaction programmatically |
WCCoreLibrary
| Function | Description |
|---|---|
GetWCAbilitySystemComponent(Actor) | Safely get ASC from any actor (handles PlayerState routing) |
IsWCPlayerCharacter(Actor) | Check if actor is a WC player character |
IsWCAICharacter(Actor) | Check if actor is a WC AI character |
WCAudioLibrary
| Function | Description |
|---|---|
RequestMusicTransition(World, MusicState) | Manually request a music state change |
PlayStinger(World, StingerDef) | Play a one-shot audio stinger |
Multiplayer Considerations
| System | Authority | Replication Method |
|---|---|---|
| Ability Activation | Server validates | GAS built-in prediction (LocalPredicted policy) |
| Attribute Changes | Server | GAS attribute replication + RepNotify |
| Inventory Operations | Server | Server RPC → replicated arrays (FastArray) |
| Equipment | Server | Server RPC → replicated slot data |
| Combat State Tags | Server | GAS tag container replication |
| Melee Hits | Server validates client prediction | Server RPC with validation |
| Audio | Client-only | Does NOT run on Dedicated Server |
| AI Logic | Server-only | Clients receive replicated state |
| Society Simulation | Server | Async actions use server RPCs |
TMap properties CANNOT be replicated in Unreal Engine. The plugin uses TArray<FEntry> patterns everywhere replication is needed. Never add replicated TMap properties.Key Multiplayer Rules
- All gameplay-critical actions (pick up, equip, use ability) must be validated on the server
- Attack chains use
PlayMontage(GAS-replicated), neverJumpToSection(local-only) - Use Client RPCs only for visual/audio feedback, never for authoritative state changes
- Set
NetExecutionPolicy = LocalPredictedon player-facing combat abilities for responsiveness
Troubleshooting
Build Errors
| Error | Solution |
|---|---|
| Unresolved externals referencing WC classes | Add the module name to your .Build.cs PublicDependencyModuleNames |
| Missing plugin: GameplayAbilities | Enable plugin in Edit → Plugins. The .uplugin should auto-enable it. |
| Could not find header file | Run "Generate Visual Studio project files" and rebuild |
| Redefinition of gameplay tag | You defined a tag in a feature module instead of WCGameplayTags.h — move it |
| Build fails on first compile | Verify the "Game development with C++" VS workload is installed |
Runtime Issues
| Symptom | Likely Cause | Solution |
|---|---|---|
| Attributes not showing in showdebug | Definitions not registered | Add to Project Settings → GAS Core → Attribute Definitions |
| Abilities not activating | Missing ASC setup or blocking tags | Verify ASC initialized; check ability's required/blocked tags |
| No interaction prompt appearing | Missing WCInteractableComponent or detection mode not configured | Verify both components are present and detection range is sufficient |
| Crosshair not showing | HUD widget not assigned or aiming tag not added | Check Project Settings → UI → Default HUD Widget Class and AimingStateTag |
| Music not playing | MusicStateMappings empty or ASC not bound to HUD | Check HUD's MusicDirectorComponent mappings; verify AWCHUD is spawning |
| Hit detection not working | Missing WCAnimNotifyState_MeleeTrace in montage | Add the notify state to your attack montage at the swing frames |
| Combat style not activating | Style not registered in Project Settings | Add to Project Settings → Combat → Registered Combat Styles |
| Equipment visual not attaching | Wrong socket name or missing WCFragment_EquipmentVisual | Check socket name matches exactly (case-sensitive) with character skeleton |
| Items not replicating in multiplayer | Operations done on client instead of server | Ensure all inventory operations check HasAuthority() and use Server RPCs |
Debug Tools
- Console command
showdebug abilitysystem: Shows all attributes, active effects, and granted abilities on the possessed pawn - AWCDummy: Drop in any level — logs all hits, effects, and attribute changes to Output Log
- WCAbilityFragment_Debug: Add to any ability definition to get lifecycle hook logging to Output Log and screen
- bDebugTraces (Project Settings → Combat): Draws melee trace spheres in the world
- bDebugInputBuffer (Project Settings → Input): Shows buffered input overlay on screen
- bEnableDebugVisualization (Project Settings → Interaction): Draws interaction detection volumes
- Output Log filter: Filter by "WCInventory", "WCCombat", "WCInteraction" etc. to see only specific module logs
Development Roadmap
The table below shows the current module status. For the full interactive roadmap — including phase breakdowns, task tracking, and detailed release planning — open the owner reference dashboard:
Open Full Roadmap Dashboard →| Module | Status | Notes |
|---|---|---|
| WCGASCore | ✅ Implemented | Full attribute pool and ability system |
| WCGASAlly | ✅ Implemented | Full RPG GAS extension (~424 headers) |
| WCInput | ✅ Implemented | Full input system with combos and buffering |
| WCInteraction | ✅ Implemented | 8 interaction types, cooperative |
| WCInventory | ✅ Implemented | Full inventory, equipment, crafting, loot |
| WCCombat | ✅ Implemented | Melee, ranged, explosives, combos, styles |
| WCUIFramework | ✅ Implemented | HUD, crosshair, CommonUI base, MVVM |
| WCAudioSuite | ✅ Implemented | Adaptive music, ambient, stingers |
| WCDynamicSociety | ✅ Implemented | Calendar, factions, crime/justice, social sim |
| DynamicRPGWorlds | ✅ Implemented | Character hierarchy, movement, camera |
| WCSaveSystem | 🔄 Planned — Phase 6 | Save slots, autosave, cloud saves, validation |
| WCRealms | 🔄 Planned — Phase 2 | Level streaming, world state, fast travel, fog of war |
| WCStories | 🔄 Planned — Phase 4 | Dialogue trees, quest system, objective tracking |
| WCAI | 🔄 Planned — Phase 4 | AI controllers, daily routines, perception, patrol |
| WCKnowledgeSuite | 🔄 Planned — Phase 3 | Achievements, lore/codex, tutorials, bestiary |