Wonderscape Creations RPG Worlds

UE5.7+ Modular RPG Framework · FAB Marketplace · Designer-first · GAS-centric · Multiplayer-ready

13Active Modules
~1,244C++ Source Files
161Native Gameplay Tags
3Dependency Layers
6Modules Fully Planned
~75%Complete
All 6 modules fully specced. WCAudioSuite, WCRealms, WCKnowledgeSuite, WCStories, WCSaveSystem, and WCAI all have complete architecture plans in the Planned Modules ★ tab. Nothing left as TBD.

Designer-First

No hardcoded values. Extensive Project Settings. Everything Blueprint-exposed and configurable from Data Assets.

GAS-Centric

Gameplay Ability System is the foundation of all mechanics. Everything flows through GAS. Never bypass it.

Fragment Composition

Items and abilities use composable fragment modules. No deep inheritance chains. Data Asset + fragments = any type.

Multiplayer-Ready

All systems server-authoritative from day one. No TMaps on replicated variables. RPCs for authority.

Tag-Driven Everything

161 tags drive state, events, and cross-module communication. All tags live in one file. Never create tags elsewhere.

Plugin-Only Architecture

100% of framework code in Plugins/DynamicRPGWorlds/. Source/ contains only sample variants.

Layer Model

Layer 3 — Integration
DynamicRPGWorlds
Assembles all feature modules into final game framework classes. Where cross-module wiring happens. Only layer that may import everything.
AWCPlayerCharacterAWCAICharacterAWCPlayerStateAWCPlayerControllerAWCGameModeBaseAWCHUDUWCCameraDirector
Layer 2 — Features
Self-contained gameplay systems
Each module is independent. Depends on WCGASCore, optionally each other. NEVER on DynamicRPGWorlds. All 5 planned modules go here.
WCInputWCInteractionWCInventoryWCCombatWCUIFrameworkWCGASAllyWCDynamicSociety WCAudioSuite ✦WCRealms ✦WCKnowledgeSuite ✦WCStories ✦WCSaveSystem ✦WCAI ✦
Layer 1 — Foundation
WCGASCore
Zero plugin dependencies. 150-slot attribute pool, ability system, and ALL 161 native gameplay tags for the entire plugin.
UWCAbilitySystemComponentUWCGASAttributePoolUWCAbilityDefinitionUWCAbilityFragmentWCGameplayTags.h

Architecture

Character Hierarchy

// UE base
ACharacter (UE)
  └── AWCCharacterBase  (Abstract — state machine, tag system, death, GAS)
      │   Components: WCCharacterMovementComponent  WCInteractionComponent  WCGASAttributeInitializer
      ├── AWCPlayerCharacter   — UGameplayCameraComponent (tag-driven rigs), ASC → PlayerState
      └── AWCAICharacter       — owns UWCCombatAbilitySystemComponent directly
  

ASC Ownership

// Player — ASC on PlayerState
AWCPlayerState  →  owns  UWCCombatAbilitySystemComponent
AWCPlayerCharacter::GetAbilitySystemComponent()  →  routes to PlayerState

// AI — ASC on character
AWCAICharacter  →  owns  UWCCombatAbilitySystemComponent

// Utility resolver
UWCCoreLibrary::GetWCAbilitySystemComponent(Actor)
  Pawn IAbilitySystemInterface → Actor's PlayerState → null
  

Input Flow

Enhanced Input → WCInputManagerComponent (PlayerController)
  → Priority-sorted Handler array
  → WCInputBuffer   (timing-sensitive queuing)
  → WCComboDetector (tree-based pattern matching)
  → Ability activation via ASC
  

Attack Chain vs Combo

Attack Chain

Same input repeated → different montage sections. Configured on MeleeCombat/RangedCombat fragment. ASC->PlayMontage() only. Never JumpToSection.

Tree Combo

Different inputs → navigate combo tree → fire abilities at nodes. UWCComboDefinition Data Asset. Detected by UWCComboDetector in WCInput.

Tag Communication

// 4 approved cross-module channels
Gameplay Tags  → event-driven state/events  (tag in WCGameplayTags.h only)
Interfaces     → type-safe calls across boundaries
Subsystems     → singleton-pattern services
Delegates      → Blueprint-accessible callbacks

// Planned module example: WCAudioSuite hears combat state
WC.State.Gameplay.Combat added to ASC
  → UWCMusicDirectorComponent registered via RegisterGameplayTagEvent()
  → transitions to CombatMusicState
  → NO direct import of WCCombat headers needed
  

Game Framework Classes

ClassLayerPurpose
AWCCharacterBaseIntegrationAbstract base — state machine, tag system, death, GAS
AWCPlayerCharacterIntegrationPlayer — camera component, routes ASC to PlayerState
AWCAICharacterIntegrationAI — owns CombatASC directly
AWCPlayerStateIntegrationServer-authoritative — owns CombatASC + CraftingComponent + new planned components
AWCPlayerControllerIntegrationHas WCInputManagerComponent, DefaultInputSetup asset
AWCHUDIntegrationHUD — widget mgmt, crosshair, hit markers + WCMusicDirectorComponent (planned)
AWCDummyIntegrationDebug target — Capsule + Mesh + CombatASC. Logs all hits for testing.

PlayerState Component Accumulation

// Components added to AWCPlayerState across phases
AWCPlayerState
  UWCCombatAbilitySystemComponent   ← WCGASCore (existing)
  UWCCraftingComponent              ← WCInventory (existing)
  UWCStoriesComponent               ← WCStories (Phase 4)
  UWCExplorationComponent           ← WCRealms (Phase 2)
  UWCKnowledgeComponent             ← WCKnowledgeSuite (Phase 3)
  // Each component defined in its feature module, CREATED here in DynamicRPGWorlds
  

Completed Modules

⚙️
WCGASCore
Layer 1 — Foundation · Zero deps
● Foundation
The bedrock. GAS infrastructure, 150-slot attribute pool, ability definitions, composable fragments, extended ASC, and all 161 native gameplay tags for the entire plugin.
GASAttributesAbilitiesFragmentsTags

Attribute System

UWCGASAttributePool150 replicated slots (Attribute_00–149) with RepNotify
UWCGASAttributeDefinitionPrimary DA per attribute — clamping, regen/degen, UI metadata, threshold events
UWCGASAttributeRegistryGameInstance Subsystem — maps tag → pool slot at runtime
UWCGASAttributeInitializerActor Component — auto-initializes pool on BeginPlay
UWCGASAttributeModData12 formula types (Linear, Exponential, SoftCap, Sigmoid…)

Ability System

UWCAbilitySystemComponentExtended ASC — definition-based API, delegate broadcasting, montage multicast
UWCGameplayAbilityBase ability class with definition access and fragment execution
UWCAbilityDefinitionPrimary DA — complete config (cost, cooldown, triggers, combo, fragments)
UWCAbilityFragmentAbstract base for composable behavior modules with tag-gated lifecycle
UWCAbilityTask_PlayMontageNotifyEnhanced montage task with AnimNotify callbacks by name

Tag Registry

WCGameplayTags.h/.cppTHE ONLY place native tags are defined. WCTags namespace. 161 tags.
🎮
WCInput
Layer 2 — Feature
● Done
Handler-based Enhanced Input routing. Priority system, input buffering, combo tree detection, context switching. Lives on PlayerController.
Enhanced InputHandlersBufferCombos
UWCInputManagerComponentPlayerController — manages handlers, contexts, buffer, detector, setup data
UWCInputBufferQueued inputs with timestamps. BufferInput(), ConsumeBufferedInput(), auto-expiry.
UWCComboDetectorTree pattern matcher. ProcessInput() navigates nodes, validates timing/tags.
WCInputHandler_CombatAbilityContext-aware combat router (airborne/crouch/weapon state gating)
WCInputHandler_ComboInputRoutes to ComboDetector for tree-based pattern matching
🤝
WCInteraction
Layer 2 — Feature
● Done
8 interaction types, 6 detection modes, cooperative multi-player interactions, widget pooling, spatial hash grid.
8 TypesCooperativeSlotsSpatial Hash
UWCInteractionComponentOn Pawn — detects, focuses, initiates. Trace/Sphere/Cone/CapsuleTrace/Closest/Custom
UWCInteractableComponentOn world actors — server-authoritative state machine, slots, queue, validation
UWCInteractionSubsystemWorld Subsystem — spatial hash grid for efficient range queries
Types: Instant Hold Ability Sequence Proximity RadialMenu ContextSensitive Custom
🎒
WCInventory
Layer 2 — Feature
● Done
Fragment-based items with 21+ fragment types. Equipment slots, set bonuses, crafting with catalysts, Diablo-style jigsaw grid, loot tables, multi-currency.
21 FragmentsEquipmentCraftingJigsawLoot
UWCItemDefinitionImmutable template (Primary DA) + fragments array
UWCItemInstanceRuntime item with mutable state (stack count, durability, custom data)
UWCEquipmentComponentEquipment slots, set bonuses, GAS integration, visual attachment

Fragment types

Stackable Durability Weight Rarity Equippable WeaponData RangedWeaponData ArmorData EquipmentVisual DualWeaponVisual AttributeModifiers Ammunition Explosive Projectile WeaponAccuracy WeaponCharge CrosshairData CombatActions Container Spatial Catalyst Consumable CurrencyValue QuestItem WorldRepresentation
⚔️
WCCombat
Layer 2 — Feature
● Done
Full combat stack — trace melee, projectile/hitscan ranged, attack chains, tree combos, ADS, reload, charge, dual wield, weapon wield/swap, combat styles.
MeleeRangedChainsCombosStylesDual Wield
UWCCombatAbilitySystemComponentExtended ASC — combat state, combo tracking, style management, equipment integration
UWCAbilityFragment_MeleeCombatAttack chains, trace config, dual-wield, unarmed
UWCAbilityFragment_RangedCombatFire modes (Single/Burst/Auto), ammo, spread/recoil, chains (Single only)
UWCAbilityFragment_AimADS — HoldToAim/Toggle, FOV zoom, drives WC.Combat.State.Aiming
UWCCombatStyleDefinitionPrimary DA — weapon requirements, passive effects, anim layer linking, priority

Anim Notifies

AnimNotifyState_MeleeTrace AnimNotifyState_AttackChainWindow AnimNotify_ChainTransitionPoint AnimNotify_ProjectileRelease AnimNotify_ReloadComplete AnimNotify_ChargeStart AnimNotify_WeaponWield AnimNotify_WeaponSwap
🖥️
WCUIFramework
Layer 2 — Feature · Redesign planned
◐ Migration
Current: HUD, tag-driven crosshair, hit markers. Planned: full Foundation layer — MVVM, screen manager (5 layers), runtime themes, widget pools, CommonUI base classes.
HUDCrosshairCommonUIMVVMTheme
🧬
WCGASAlly
Layer 2 — Feature · 423 files
● Done
RPG layer — Heritage, skill trees, leveling, status effects with synergy chains, multi-layer damage, factions, resistance AND the full AI stack (BT/StateTree/EQS/Squads/Boss).
HeritageSkillTreesStatusEffectsAI StackFactions
HeritageRace/class/subrace — base stats, abilities, restrictions
StatusEffectEffects with evolution rules and synergy chains (Wet + Lightning = Shocked)
SkillTreeSkill trees with build presets — nodes grant abilities/effects on unlock
WCGASAICombatCompCombat AI — threat system, targeting
WCGASSquadCompSquad management for coordinated group AI
WCGASBossPhaseDataBoss phase transitions
🏛️
WCDynamicSociety
Layer 2 — Feature · 178 files
● Done
Social simulation DATA layer. NPC identity, personality, factions, reputation, calendar/time, crime & justice. Data only — AI behavior consumed by WCAI (planned).
NPC DataFactionsCalendarCrime
🔗
DynamicRPGWorlds
Layer 3 — Integration (top)
● Integration
Assembles all feature modules into final framework classes. Where cross-module wiring happens. Player/AI characters, game mode, camera, locomotion.
CharactersCameraLocomotionFramework
🛠️
Editor Modules (3)
Build-time only — not shipped
● Editor
Custom asset editors, factories, validation tools. WCCombatEditor, WCGASAllyEditor, WCDynamicSocietyEditor. Never included in shipped builds.
WCCombatEditorWCGASAllyEditorWCDynamicSocietyEditor

Planned Modules

Click any tab inside a module card to navigate its spec. All 5 modules are fully architected and ready to implement.
🎵
WCAudioSuite
Layer 2 Feature · Phase 2 · Start here — FRSound experience applies directly
✦ Phase 2
Tag-driven adaptive music system with layered states and crossfading. Ambient zone volumes with priority stacking. Combat audio stingers. WCCameraDirector-style tag → music mapping. Pure tag consumption — no direct imports of other feature modules.

Core Pattern (mirrors WCCameraDirector)

UWCMusicDirectorComponent (on AWCHUD)
  TArray<FWCMusicStateMapping> MusicStateMappings  // ordered by priority
  FWCMusicStateMapping: ActivationTag + MusicState + Priority

// Example config
Priority 300: WC.State.Gameplay.Combat       → CombatMusicState
Priority 200: WC.Character.State.Cinematic   → CinematicMusicState
Priority 100: WC.Realms.Location.Type.Dungeon → DungeonMusicState
Default:      (no match)                           → ExplorationMusicState
      

Subsystem Responsibilities

UWCAudioSubsystemWorld Subsystem — active music state, ambient zone stack, stinger queue, audio component pool. RequestMusicTransition(), PushAmbientZone(), PlayStinger().
UWCMusicDirectorComponentOn AWCHUD — watches ASC tags via RegisterGameplayTagEvent(), signals subsystem to transition. SetOverrideState() for boss fights/cutscenes.
AWCAmbientZoneVolumeWorld Volume — on overlap registers/unregisters with AudioSubsystem. Priority-stacked, highest wins.
UWCMusicStateDefinitionPrimary DA — layers array, CrossfadeInTime, CrossfadeOutTime, TransitionMode (Crossfade/CutImmediate/WaitForBar/WaitForBeat), IntroStinger, OutroStinger
UWCMusicLayerDefinitionData Asset — LoopingSound (MetaSound/SoundCue), DefaultVolume, LayerTag, bStartMuted
UWCAmbientZoneDefinitionPrimary DA — DayAmbientSounds, NightAmbientSounds, IndoorAmbientSounds, Priority, RequiredTags, ZoneReverb
UWCCombatAudioDefinitionPrimary DA — CombatStartStingers, KillStingers, VictoryStingers, HitReactionSounds, StingerCooldown
UWCStingerDefinitionPrimary DA — StingerSound, TriggerEventTag, Volume, bIs2D
UWCAudioSettingsDefaultExplorationMusicState, DefaultCombatMusicState, MusicMasterVolume, AmbientMasterVolume, DefaultMusicTransitionTime (2.0s)
WCAudioSuite/Public/ Music/ WCMusicDirectorComponent.h // Tag→music mapping (mirrors WCCameraDirector) WCMusicStateDefinition.h // Primary DA: layers, crossfade, transition mode WCMusicLayerDefinition.h // Primary DA: single audio layer WCMusicTypes.h // EWCMusicTransitionMode, FWCMusicStateMapping Ambient/ WCAmbientZoneDefinition.h // Primary DA: day/night/indoor variants AWCAmbientZoneVolume.h // AVolume: activates ambient on overlap Combat/ WCCombatAudioDefinition.h // Primary DA: stingers, hit reactions Stingers/ WCStingerDefinition.h // Primary DA: one-shot + trigger tag Subsystems/ WCAudioSubsystem.h // World Subsystem: all audio state Settings/ WCAudioSettings.h Library/ WCAudioLibrary.h

New Tags (add to WCGameplayTags.h)

WCTags::Audio_State_MusicTransitioning
WCTags::Audio_Event_MusicStateChanged
WCTags::Audio_Event_StingerPlayed
WCTags::Audio_Layer_BaseMusicLayer
WCTags::Audio_Layer_CombatPercussion
WCTags::Audio_Layer_Melody
WCTags::Audio_Layer_Ambient
WCTags::Audio_Layer_UI

Build.cs Dependencies

Public
Core
Engine
GameplayTags
AudioMixer
WCGASCore
Private
WCDynamicSociety
MetasoundEngine
DeveloperSettings
UWCMusicDirectorComponent created on AWCHUD in DynamicRPGWorlds. AWCHUD::SetupAudioDirector() called after ASC resolves.
UWCAudioSubsystem watches WCDynamicSociety CalendarSubsystem for time-of-day to switch day/night ambient variants.
Stinger bindings consume tags: WC.State.Gameplay.Combat → combat start stinger, WC.Combat.Event.Kill → kill stinger, WC.Realms.Event.LocationDiscovered → discovery stinger (cross-module via tags only).
No direct combat module imports. All music state changes driven purely by ASC tag events.
🌍
WCRealms
Layer 2 Feature · Phase 2 · Parallel with WCAudioSuite
✦ Phase 2
Level streaming and world management. Location discovery via volumes or viewpoints. Fast travel between discovered points. World state persistence for interactive objects. Realm transition volumes for level streaming. Pattern: WCInteraction (World Subsystem + Volume actors + component-on-pawn).

4 Sub-systems

UWCDiscoverySubsystemWorld Subsystem — tracks discovered locations, fires GAS events, feeds fast travel list
UWCFastTravelSubsystemWorld Subsystem — unlock/lock travel points, execute teleport, show loading screen widget
UWCWorldStateSubsystemWorld Subsystem — captures/restores FWCWorldStateSnapshot for all IWCWorldStateSaveable actors
UWCLevelStreamingSubsystemWorld Subsystem — async load/unload UWCRealmDefinition streaming levels
UWCExplorationComponentOn AWCPlayerState — per-player TArray<FGameplayTag> DiscoveredLocationTags. SaveGame + replicated.

Discovery Flow

AWCLocationVolume overlap (or UWCViewpointComponent radius scan)
  → UWCDiscoverySubsystem::ReportLocationDiscovered(PlayerController, LocationDef)
  → UWCExplorationComponent::SetLocationDiscovered(LocationTag)
  → GAS event WCTags::Realms_Event_LocationDiscovered on player ASC
  → WCKnowledgeSuite listens → unlocks codex/achievement (cross-module via tag)
      
UWCLocationDefinitionPrimary DA — LocationName, LocationTag, CategoryTags, bEnableFastTravel, FastTravelSpawnTransform, DiscoveryType
AWCLocationVolumeAVolume — TSoftObjectPtr<UWCLocationDefinition>, bAutoDiscoverOnOverlap, EWCLocationVolumeMode. Server authoritative.
UWCViewpointComponentOn world actors — radius survey at interval → discovers visible locations (for viewpoint towers)
AWCRealmTransitionVolumeAVolume — references UWCRealmDefinition, triggers async level streaming on overlap
UWCRealmDefinitionPrimary DA — streaming level list, initial state, ambient audio reference
IWCWorldStateSaveableInterfaceActors opt-in — GetWorldStateGUID(), OnCaptureState(), OnLoadState(). Use for chests, doors, NPCs alive/dead.
WCRealms/Public/ Discovery/ WCLocationDefinition.h WCDiscoverySubsystem.h WCExplorationComponent.h AWCLocationVolume.h WCViewpointComponent.h WCDiscoveryTypes.h FastTravel/ WCFastTravelSubsystem.h WCFastTravelTypes.h WorldState/ WCWorldStateSubsystem.h WCWorldStateTypes.h WCWorldStateSaveableInterface.h WCWorldStateSaveableComponent.h Streaming/ WCRealmDefinition.h WCLevelStreamingSubsystem.h AWCRealmTransitionVolume.h WCStreamingTypes.h Settings/ WCRealmsSettings.h

New Tags

WCTags::Realms_Event_LocationDiscovered
WCTags::Realms_Event_FastTravelCompleted
WCTags::Realms_Event_RealmTransitionStarted
WCTags::Realms_Event_RealmTransitionCompleted
WCTags::Realms_State_FastTraveling
WCTags::Realms_State_Transitioning
WCTags::Realms_Location_Type_Town
WCTags::Realms_Location_Type_Dungeon
WCTags::Realms_Location_Type_Landmark
WCTags::Realms_Location_Type_FastTravel

Build.cs

Public
Core
Engine
NavigationSystem
WCGASCore
Private
WCUIFramework
LevelSequence
DeveloperSettings
UWCExplorationComponent added to AWCPlayerState constructor in DynamicRPGWorlds.
AWCGameModeBase calls UWCLevelStreamingSubsystem for initial realm load.
WCSaveSystem calls UWCWorldStateSubsystem::CaptureWorldSnapshot() before save, RestoreWorldSnapshot() after load.
WCTags::Realms_Event_LocationDiscovered consumed by WCKnowledgeSuite achievement tasks and codex unlock conditions.
📖
WCKnowledgeSuite
Layer 2 Feature · Phase 3
✦ Phase 3
Four systems in one module: Achievement system (GAS event-triggered tasks), Codex/lore entries (unlocked by events or location discovery), Bestiary (progressive reveal per enemy kill count), Tutorial system (tag-triggered, priority-queued, non-intrusive). All driven by ASC tags from other modules.
UWCKnowledgeSubsystemGameInstance Subsystem — definition registry, global GAS event subscription, routes events to all UWCKnowledgeComponent instances
UWCKnowledgeComponentOn AWCPlayerState — TArray<FGameplayTag> UnlockedAchievements, UnlockedCodexEntries, SeenTutorials. FWCBestiaryEntryState per creature. FastArray replicated.
UWCTutorialSubsystemWorld Subsystem — TQueue of pending tutorials, watches ASC tags, shows one at a time via widget. AdvanceTutorialStep(), DismissTutorial().

Achievement task flow

UWCKnowledgeSubsystem::InitializePlayerKnowledge(KnowledgeComp)
  → starts UWCAchievementTask instances for incomplete achievements
  → subscribes to AddGameplayEventTagContainerDelegate() for relevant event tags
  → UWCAchievementTask::AddProgress() on matching event
  → CompleteTask() → all tasks done → unlock achievement
  → OnAchievementUnlocked → WCAudioSuite plays stinger
      
UWCAchievementDefinitionPrimary DA — AchievementTag, CategoryTag, Tasks (Instanced), Rewards, bSecret, bRepeatable
UWCAchievementTaskAbstract Blueprintable — RequiredProgress, BeginTask(), AddProgress(), CompleteTask(). EditInlineNew.
UWCLoreEntryDefinitionPrimary DA — EntryTag, CategoryTag, EntryBody, UnlockTrigger (OnGASEvent/OnLocationDiscovered/OnScripted), UnlockEventTag, RequiredKnowledgeTags (lore chains)
UWCBestiaryEntryDefinitionPrimary DA — CreatureTypeTag (links to WCGASAlly heritage tag), WeaknessTags, ResistanceTags, EWCBestiaryRevealLevel per field, KillsForFullReveal
UWCTutorialDefinitionPrimary DA — Steps array (FWCTutorialStep: text, icon, HighlightUITag), TriggerTag, SkipConditionTag, Priority, bShowOnce

Built-in Achievement Tasks

WCAchievementTask_GASEventCount occurrences of a gameplay event tag (e.g., WC.Combat.Event.Kill x50)
WCAchievementTask_HasTagCheck ASC has a specific tag (state-based achievements)
WCAchievementTask_KillCountCount WC.Combat.Event.Kill events (per enemy type tag optional)
WCAchievementTask_DiscoverLocationListens to WCTags::Realms_Event_LocationDiscovered
WCAchievementTask_LevelReachedListens to WCGASAlly leveling event tag

New Tags

WCTags::Knowledge_Achievement_Unlocked
WCTags::Knowledge_Achievement_Progress
WCTags::Knowledge_Codex_Unlocked
WCTags::Knowledge_Codex_Category_Combat
WCTags::Knowledge_Codex_Category_World
WCTags::Knowledge_Bestiary_Encountered
WCTags::Knowledge_Bestiary_Killed
WCTags::Knowledge_Bestiary_FullyRevealed
WCTags::Knowledge_Tutorial_Active
WCTags::Knowledge_Tutorial_Dismissed
WCTags::Knowledge_Achievement_Category_Combat
WCTags::Knowledge_Achievement_Category_Exploration

Build.cs

Public
WCGASCore
WCDynamicSociety
UMG
Private
WCGASAlly
WCUIFramework
UWCKnowledgeComponent added to AWCPlayerState constructor in DynamicRPGWorlds.
UWCKnowledgeSubsystem::InitializePlayerKnowledge() called from AWCPlayerState::BeginPlay().
WCSaveSystem serializes UWCKnowledgeComponent arrays as part of player data.
WCAudioSuite: WCTags::Knowledge_Achievement_Unlocked fires achievement stinger.
WCRealms: Realms_Event_LocationDiscovered consumed by WCAchievementTask_DiscoverLocation and codex unlock conditions.
📜
WCStories
Layer 2 Feature · Phase 4 · Narrative Pro patterns referenced
✦ Phase 4
Dialogue tree system with branching nodes and condition/event objects. Quest system as a state machine (states → branches → tasks). Abstract Blueprintable tasks for designer extensibility. Conditions check ASC tags, inventory, heritage, and reputation. Events grant quests, items, GAS events, reputation changes.

Quest State Machine

UWCQuest (Blueprintable UObject)
  TArray<UWCQuestState*> States
  TArray<UWCQuestBranch*> Branches
  UWCQuestState* CurrentState
  EWCQuestCompletion: NotStarted | Started | Succeeded | Failed

  └── UWCQuestState   — a node in the SM
        └── UWCQuestBranch — transition between states, holds tasks
              └── UWCQuestTask (abstract Blueprintable, EditInlineNew)
      
UWCStoriesComponentOn AWCPlayerState — ActiveQuests, CompletedQuests, ActiveDialogue. BeginQuest(), BeginDialogue(), CompleteQuestTask().
UWCQuestSubsystemGameInstance Subsystem — quest registry, global events (OnQuestStarted, OnQuestSucceeded)

Dialogue Tree

UWCDialogue (Blueprintable UObject)
  TArray<UWCDialogueNode_NPC*> RootNodes   (entry points)
  TArray<FSpeakerSelector> Speakers

  └── UWCDialogueNodeBase
        TArray<UWCStoryCondition*> Conditions (Instanced — all must pass)
        TArray<UWCStoryEvent*> Events (Instanced — fire on reach)
        TArray<UWCDialogueNode_NPC*> NPCReplies
        TArray<UWCDialogueNode_Player*> PlayerReplies
      
FWCDialogueLineFText + EWCLineDuration (Default/WhenAudioEnds/AfterReadingTime/AfterDuration/Never) + DialogueSound + DialogueMontage + FacialAnimation + Conditions (alternative lines)
UWCDialogueSubsystemWorld Subsystem — active dialogue management
UWCDialogueSpeakerDataData Asset — speaker identity, references WCDynamicSociety NPC identity tags

Built-in Conditions

WCStoryCondition_HasTagChecks ASC for gameplay tag via UWCCoreLibrary::GetWCAbilitySystemComponent()
WCStoryCondition_HasItemChecks WCInventory for item count
WCStoryCondition_HeritageChecks WCGASAlly heritage (race/class/subrace)
WCStoryCondition_ReputationChecks WCDynamicSociety reputation value for a faction

Built-in Events

WCStoryEvent_GrantQuestCalls UWCStoriesComponent::BeginQuest()
WCStoryEvent_GrantItemAdds items via UWCInventoryComponent
WCStoryEvent_FireGASEventCalls ASC->SendGameplayEvent() on target
WCStoryEvent_ModReputationModifies WCDynamicSociety reputation for a faction
WCQuestTask_GoToLocationOverlap trigger at target location (uses WCRealms volume or manual trigger)
WCQuestTask_ObtainItemSubscribes to UWCInventoryComponent::OnItemAdded — monitors for item count
WCQuestTask_KillEnemyListens to WCTags::Combat_Event_Kill via ASC delegate
WCQuestTask_TalkToNPCListens for WCStories dialogue completion event tag
WCQuestTask_GASEventWaits for a specific gameplay event tag on player ASC

New Tags

WCTags::Quest_State_Active / Succeeded / Failed
WCTags::Quest_Event_Started / Updated / Succeeded / Failed
WCTags::Dialogue_State_Active
WCTags::Dialogue_Event_Started / Finished / NodeReached

Build.cs

Public
WCGASCore
WCInventory
WCDynamicSociety
GameplayTasks
UMG
Private
WCGASAlly
WCUIFramework

Integration

UWCStoriesComponent added to AWCPlayerState in DynamicRPGWorlds.
Editor module WCStoriesEditor: custom graph editor for UWCQuest (state nodes + branch edges) and UWCDialogue (NPC/Player node graph).
WCAI (Phase 4) references WCStories for dialogue triggering from AI behavior.
💾
WCSaveSystem
Layer 2 Feature · Phase 6 · Final module
✦ Phase 6
Serialization for all game state. Multiple slots with metadata. Autosave with configurable intervals. Each WC system serializes its own data. Opt-in interface for world actors. FMemoryWriter/FMemoryReader + FObjectAndNameAsStringProxyArchive pattern. GUID-based actor resolution.
UWCSaveSubsystemGameInstance Subsystem (persists across level transitions) — Save(), Load(), DeleteSave(), SetAutosaveEnabled(), IsLoading(). Iterates IWCSaveableInterface actors via GetAllActorsWithInterface(). GUID QuickLookupMap.
IWCSaveableInterfaceActors opt-in — GetSaveGUID() (FGuid, stored as UPROPERTY(SaveGame)), OnPreSave(), OnPostLoad(), ShouldSaveTransform(), ShouldDynamicSpawn().
UWCSaveableComponentConvenience component wrapping the interface for Blueprint actors
UWCSaveGameExtends USaveGame — TMap<FGuid, FWCSavedActorRecord>, FWCSavedPlayerRecord, plus byte arrays for each system. SavedDataVersion + Serialize(FArchive&) for versioning.
FWCSavedActorRecordFGuid ActorGUID, FName ActorName, FTransform, bDestroyed, bNeedsDynamicSpawn, TSoftClassPtr ActorSoftClass, TArray<uint8> ByteData, TArray<FWCSavedComponentRecord>
FWCSavedPlayerRecordController + Pawn + PlayerState serialized records
FWCSaveSlotInfoSlotName, SlotIndex, SavedAt (FDateTime), LevelName, playtime metadata — used for UI slot picker
EWCSaveGameVersionVersion namespace for Epic's versioning pattern. Increment on breaking save format changes. Used in UWCSaveGame::Serialize().
UWCSaveSettingsMaxSaveSlots (10), AutosaveIntervalSeconds (300), bEnableAutosave, SaveGameClass, bSaveTransforms, bSaveDynamicActors

Each system provides its own serialization helpers called by UWCSaveSubsystem

WCGASCore attributesUWCGASAttributeRegistry exposes SerializeAttributeState(FArchive&) / DeserializeAttributeState() — writes all pool slot values
WCInventoryUWCInventoryComponent + UWCEquipmentComponent use FMemoryWriter on their FastArray containers marked UPROPERTY(SaveGame)
WCStoriesUWCStoriesComponent serializes active/completed quest IDs + per-quest CurrentStateID + task progress
WCGASAllyWCGASCurriculumSaveLoadLib and WCGASFeatSaveLoadLib (already exist in WCGASAlly)
WCDynamicSocietyCalendarSubsystem exposes current in-game time for serialization
WCRealmsUWCExplorationComponent::DiscoveredLocationTags + UWCWorldStateSubsystem::CaptureWorldSnapshot()
WCKnowledgeSuiteUWCKnowledgeComponent arrays (achievements, codex, bestiary progress, seen tutorials)

New Tags

WCTags::Save_Event_SaveStarted
WCTags::Save_Event_SaveFinished
WCTags::Save_Event_LoadStarted
WCTags::Save_Event_LoadFinished
WCTags::Save_State_SavingDisabled

Build.cs

Public
WCGASCore
Core
Engine
NetCore
Private
WCInventory
WCGASAlly
WCStories
WCDynamicSociety
UWCSaveSubsystem registers automatically as GameInstanceSubsystem — no explicit wiring needed.
AWCGameInstance hooks: OnPreLevelTransitionSave("autosave",0) and OnPostLevelTransitionLoad("autosave",0) for seamless world transition saves.
UWCSaveSubsystem::SetSavingDisabled(true) called during combat/cutscenes to prevent mid-action saves.
Note: WCSaveSystem.Build.cs lists WCStories as a private dep — this means Phase 6 can't ship until Phase 4 (WCStories) is complete.
🤖
WCAI
Layer 2 Feature · Phase 4 · Routine AI only — combat AI stays in WCGASAlly
✦ Phase 4
Standalone behavioral layer for NPC daily routines. Consumes WCDynamicSociety schedule/identity/faction data. When WC.State.Gameplay.Combat is added to an NPC's ASC, WCAI suspends and WCGASAlly's combat stack takes over automatically. When combat ends, routine resumes from last checkpoint. WCGASAlly's WCGASAICombatComp, BT combat tasks, EQS, StateTree, and Squads are NOT replicated here.
Critical design boundary — never cross it:
WCGASAlly owns: combat AI (WCGASAICombatComp, threat, targeting, BT combat tasks, EQS, StateTree, Squads, Boss phases)
WCAI owns: routine AI (schedules, ambient behavior, patrol, perception, dialogue triggers)

Combat handoff

AWCNPCController watches NPC's ASC via RegisterGameplayTagEvent():

  WC.State.Gameplay.Combat ADDED
    → EnterCombatState()
    → SuspendRoutine() saves checkpoint
    → WCGASAlly's WCGASAICombatComp takes over (already on NPC)

  WC.State.Gameplay.Combat REMOVED
    → ExitCombatState()
    → ResumeRoutine() restores checkpoint
    → WCAI routine resumes

// AWCNPCController NEVER reimplements combat logic — it yields to the existing stack
      
AWCNPCControllerAIController base — routine state machine, perception, GAS tag watcher. Creates RoutineComponent + WCPerceptionComponent in constructor. OnPossess() loads AI Profile, starts DefaultBehaviorTree.
AWCNPCCharacterExtends AWCAICharacter (DynamicRPGWorlds) — adds SocialData (WCDynamicSociety) and DefaultAIProfile references. Registers with UWCAISubsystem on BeginPlay.
UWCNPCRoutineComponentOn AWCNPCController — reads DS CalendarSubsystem for current schedule slot, selects UWCRoutineGoal subclass, manages BeginGoal/EndGoal lifecycle. SuspendRoutine() / ResumeRoutine() for combat handoff.
UWCNPCPerceptionComponentExtends UAIPerceptionComponent — GetNearestPlayer(), GetPerceivedActorsByFaction(), IsPlayerHostile() via WCDynamicSociety faction data. Adds WC.AI.State.Alerted tag on alert.
UWCAIProfileDefinitionPrimary DA — DefaultBehaviorTree, DefaultPatrolRoute, PersonalityTags, DialogueTriggerChance, AlertRadius, CombatEntryRadius, bFleeOnLowHealth, ScheduleOverrides
UWCPatrolRouteDefinitionPrimary DA — TArray<FWCPatrolWaypoint>, bLooping. FWCPatrolWaypoint: WorldLocation, WaitDuration, ActionTag.
UWCAISubsystemWorld Subsystem — NPC registry, spatial query (GetNPCsInRadius), faction group queries, AI LOD (NPCs beyond FullAIRadius run reduced tick), SetGlobalAIEnabled() for cutscenes.

Abstract Routine Goal (same pattern as UWCQuestTask)

UWCRoutineGoal (Abstract, Blueprintable, EditInlineNew)
  FGameplayTag GoalTag        // e.g., WC.AI.Routine.Working
  float MaxDuration           // 0 = until schedule changes
  BeginGoal(AWCNPCController*)   // BlueprintNativeEvent
  TickGoal(float DeltaTime)      // BlueprintNativeEvent
  EndGoal()                      // BlueprintNativeEvent
  IsGoalComplete()               // BlueprintNativeEvent
      

Built-in Goals

WCRoutineGoal_GoToLocationMove to a named location tag (resolved via UWCAISubsystem spatial query)
WCRoutineGoal_WaitIdle at current position for duration (wander in small radius variant)
WCRoutineGoal_FollowRouteExecute ordered UWCPatrolRouteDefinition waypoints
WCRoutineGoal_SocializeFind nearest NPC of matching faction via UWCAISubsystem, trigger idle interaction anim
WCRoutineGoal_StartDialogueTriggers WCStories UWCStoriesComponent::BeginDialogue() on nearest player's PlayerState

Schedule Tag → Goal Mapping

WC.AI.Routine.Sleeping    → GoToLocation (bed) + Wait
WC.AI.Routine.Working     → GoToLocation (worksite) + Wait
WC.AI.Routine.Patrolling  → FollowRoute
WC.AI.Routine.Socializing → Socialize
WC.AI.Routine.Shopping    → GoToLocation (market)
WC.AI.Routine.Eating      → GoToLocation (tavern) + Wait
WC.AI.Routine.Idle        → Wait (wander)
      

Default BT Structure (ships as example BT_WC_NPC_Default)

Root → Selector
  ├── [Decorator: IsInCombat]       → Exit (WCGASAlly handles)
  ├── [Decorator: IsIncapacitated]  → WCBTTask_Wait
  └── Sequence (Routine)
      ├── WCBTService_UpdateRoutine    // re-evaluates schedule each tick
      ├── WCBTService_UpdatePerception // updates blackboard
      └── WCBTTask_ExecuteRoutineGoal  // runs CurrentGoal
      
WCAI/Public/ Controllers/ AWCNPCController.h // AIController: routine SM, combat handoff AWCNPCCombatController.h // Thin bridge to WCGASAlly on combat entry Characters/ AWCNPCCharacter.h // Extends AWCAICharacter, adds SocialData ref Components/ WCNPCRoutineComponent.h // Schedule → goal selection, suspend/resume WCNPCPerceptionComponent.h // Extends UAIPerceptionComponent + faction filter Goals/ WCRoutineGoal.h WCRoutineGoal_GoToLocation.h WCRoutineGoal_Wait.h WCRoutineGoal_FollowRoute.h WCRoutineGoal_Socialize.h WCRoutineGoal_StartDialogue.h WCRoutineGoalTypes.h BehaviorTree/Tasks/ WCBTTask_ExecuteRoutineGoal.h WCBTTask_FindSocialTarget.h WCBTTask_MoveToNamedLocation.h WCBTTask_TriggerDialogue.h WCBTTask_SetRoutineTag.h BehaviorTree/Decorators/ WCBTDecorator_IsInRoutine.h WCBTDecorator_ScheduleAllows.h WCBTDecorator_HasRoutineGoal.h BehaviorTree/Services/ WCBTService_UpdateRoutine.h WCBTService_UpdatePerception.h DataAssets/ WCAIProfileDefinition.h WCPatrolRouteDefinition.h Subsystems/ WCAISubsystem.h Settings/ WCAISettings.h

New Tags

WCTags::AI_State_Idle / InRoutine / Alerted / Fleeing / Suspended
WCTags::AI_Routine_Sleeping / Working / Patrolling
WCTags::AI_Routine_Socializing / Shopping / Eating / Idle
WCTags::AI_Personality_Timid / Aggressive / Friendly / Neutral
WCTags::AI_Event_RoutineGoalCompleted / AlertedToPlayer
WCTags::AI_Event_CombatEntered / CombatExited

Build.cs

Public
WCGASCore
WCDynamicSociety
AIModule
NavigationSystem
Private
WCGASAlly
WCStories
GameplayStateTree
StateTreeModule

Integration

AWCNPCCharacter extends AWCAICharacter (DynamicRPGWorlds) — already in the hierarchy. No new PlayerState component needed.
AWCGameModeBase optionally references UWCAISettings::DefaultNPCControllerClass for auto-possessed NPCs.
UWCNPCRoutineComponent queries WCDynamicSociety CalendarSubsystem for current time slot and NPCSocialComponent for schedule asset.
Combat handoff is automatic via ASC tag watch — no code changes needed in WCGASAlly.
UWCRoutineGoal_StartDialogue (private dep on WCStories) calls UWCStoriesComponent::BeginDialogue() on nearest player's PlayerState.
AI LOD: NPCs beyond UWCAISettings::FullAIRadius (5000 units) run reduced RoutineUpdateInterval (5.0s default). Beyond MaxActiveFullAINPCs (20), fallback to minimal state.

Build Roadmap

Dependency order matters. WCSaveSystem depends on WCStories (private dep), so it must come after Phase 4. WCKnowledgeSuite benefits from WCRealms tags being registered first. Build in phase order.
PhaseModuleDepends On (Private)Adds to PlayerStateNew Tags
2🎵 WCAudioSuiteWCDynamicSociety, MetasoundEngine8 (Audio.*)
2🌍 WCRealmsWCUIFramework, LevelSequenceUWCExplorationComponent10 (Realms.*)
3📖 WCKnowledgeSuiteWCGASAlly, WCUIFrameworkUWCKnowledgeComponent16 (Knowledge.*)
4📜 WCStoriesWCGASAlly, WCUIFrameworkUWCStoriesComponent11 (Quest.* Dialogue.*)
4🤖 WCAIWCGASAlly, WCStories, GameplayStateTree21 (AI.*)
6💾 WCSaveSystemWCInventory, WCGASAlly, WCStories, WCDynamicSociety5 (Save.*)

Cross-Module Tag Dependencies (Planned)

// Which modules consume tags from other planned modules
WCAudioSuite  → listens: WC.Realms.Event.LocationDiscovered (discovery stinger)
               → listens: WC.Knowledge.Achievement_Unlocked (achievement stinger)
               → listens: WC.State.Gameplay.Combat (combat music — existing)

WCKnowledgeSuite → listens: WC.Realms.Event.LocationDiscovered (codex/achievement unlock)
                 → listens: WC.Combat.Event.Kill (kill-count achievements — existing)

WCStories     → condition checks: WCInventory, WCGASAlly, WCDynamicSociety (via interfaces)
              → task tasks: listens to WCInventory::OnItemAdded, WC.Combat.Event.Kill

WCAI          → watches: WC.State.Gameplay.Combat on NPC ASC → suspend/resume
              → reads: WCDynamicSociety CalendarSubsystem + NPCSocialComponent (schedule)
              → private: WCStories for WCRoutineGoal_StartDialogue

WCSaveSystem  → calls serialization on: WCGASCore, WCInventory, WCGASAlly, WCStories,
                 WCDynamicSociety, WCRealms, WCKnowledgeSuite

// All ~75 new planned tags still go to WCGASCore/Public/WCGameplayTags.h
  

Rules & Patterns

The 6 Immutable Rules

Rule 1 — Architecture
Dependencies flow upward only
Lower layers never reference higher layers. Feature modules never depend on DynamicRPGWorlds. Only DynamicRPGWorlds may depend on all feature modules. Violating this collapses the entire architecture.
Rule 2 — Tags
All tags in WCGameplayTags.h only
Never define native tags in feature modules. All 50+ new planned module tags go to WCGASCore/Public/WCGameplayTags.h in the WCTags namespace. Exception: UE_DEFINE_GAMEPLAY_TAG_STATIC for handler-local tags.
Rule 3 — Replication
No TMap on replicated variables
TMaps are NOT replicable. Use TArray or FastArray. This applies even to variables that aren't yet replicated — plan for it. Affects UWCSaveGame, UWCExplorationComponent, UWCKnowledgeComponent, etc.
Rule 4 — Code Location
Plugin-only architecture
All framework code in Plugins/DynamicRPGWorlds/. Source/ is for sample variants only. Every new module gets a folder in Plugins/DynamicRPGWorlds/Source/WC[Name]/.
Rule 5 — Combat
Never use JumpToSection for replicated chains
Use ASC->PlayMontage() only. JumpToSection() and Montage_SetNextSection() are local-only — never replicated to simulated proxy clients.
Rule 6 — Engine
No deprecated UE APIs
UE5.7+ only. IWYU enabled. Warnings as Errors on WCGASCore, WCGASAlly, WCDynamicSociety. Unity builds disabled on complex modules. Apply same standards to all new modules.

Core Design Patterns

Fragment Composition — Items and Abilities

UWCItemDefinition (Primary DA) + TArray<UWCItemFragment*> = any item type (no C++ subclassing)
UWCAbilityDefinition (Primary DA) + TArray<UWCAbilityFragment*> = any ability type

// Planned modules follow same pattern:
UWCAchievementDefinition + TArray<UWCAchievementTask*> = any achievement type
UWCQuest + TArray<UWCQuestState*> + TArray<UWCQuestTask*> = any quest structure
    

Tag-Driven Cross-Module Communication

// Cross-module channels (in priority order)
Gameplay Tags   → event-driven state/events (preferred)
Interfaces      → type-safe calls  (IWCSaveableInterface, IWCWorldStateSaveable)
Subsystems      → singleton services  (UWCDiscoverySubsystem, UWCAudioSubsystem)
Delegates       → Blueprint callbacks

// NEVER: feature module #includes another feature module without Build.cs declaration
// NEVER: planned module includes DynamicRPGWorlds headers
    

Integration Layer Wiring Pattern

// Component defined in feature module, CREATED in DynamicRPGWorlds
WCRealms defines UWCExplorationComponent
  → DynamicRPGWorlds AWCPlayerState constructor creates it

WCKnowledgeSuite defines UWCKnowledgeComponent
  → DynamicRPGWorlds AWCPlayerState constructor creates it

WCStories defines UWCStoriesComponent
  → DynamicRPGWorlds AWCPlayerState constructor creates it

WCAudioSuite defines UWCMusicDirectorComponent
  → DynamicRPGWorlds AWCHUD::BeginPlay creates it (after ASC resolves)
    

Quick Reference

Naming — C++

TypePattern
ComponentsWC[Module]Component
Data AssetsWC[Type]Definition / Data
SettingsWC[Module]Settings
SubsystemsWC[Purpose]Subsystem
InterfacesIWC[Purpose]Interface
LibrariesWC[Module]Library
Item FragmentsWCFragment_[Name]
Ability FragmentsWCAbilityFragment_[Name]
Input HandlersWCInputHandler_[Name]

Gameplay Tag Format

WC.[Module].[Category].[Subcategory]

// Existing
WC.Combat.State.Aiming
WC.Combat.Event.HitConfirmed
WC.State.Gameplay.Combat
WC.State.Gameplay.Exploring

// Planned (50 new tags across 5 modules)
WC.Audio.State.MusicTransitioning
WC.Realms.Event.LocationDiscovered
WC.Knowledge.Achievement.Unlocked
WC.Quest.State.Active
WC.Dialogue.State.Active
WC.Save.Event.SaveStarted

Key File Locations

FilePath
Master ReferencePlugins/DynamicRPGWorlds/CLAUDE.md
All Gameplay TagsWCGASCore/Public/WCGameplayTags.h
Tag DefinitionsWCGASCore/Private/WCGameplayTags.cpp
Base AbilityWCGASCore/Public/GAS/WCGameplayAbility.h
Base Item FragmentWCInventory/Public/Fragments/WCItemFragment.h
Base Ability FragmentWCGASCore/Public/GAS/WCAbilityFragment.h
Combat Ability BaseWCCombat/Public/Abilities/WCGameplayAbility_Combat.h
Player CharacterDynamicRPGWorlds/Public/Character/WCPlayerCharacter.h
Build.cs templateWCInventory/WCInventory.Build.cs
Project RootU:\UE Projects\Diversion\WC_RPG_Worlds

Debug Tools

showdebug abilitysystem   // GAS state, attributes, effects
showdebug gameplaytags    // Active tags on actors
showdebug input           // Enhanced Input debug

AWCDummy  // Drop in level — logs all GAS hits
UWCAbilityFragment_Debug  // Add to any ability

// Per-module debug flags in Project Settings:
UWCInputSettings       → bEnableInputLogging
UWCInteractionSettings → bEnableDebugVisualization
UWCCombatSettings      → bEnableTraceDebug
// Add bDebugX to each new module's Settings class

Build Commands

"<UE5_ROOT>/Engine/Build/BatchFiles/Build.bat"
  WC_RPG_Worlds Win64 Development
  -Project="U:/UE Projects/Diversion/
            WC_RPG_Worlds/WC_RPG_Worlds.uproject"

"<UE5_ROOT>/Engine/Build/BatchFiles/
  GenerateProjectFiles.bat"
  "U:/UE Projects/Diversion/
   WC_RPG_Worlds/WC_RPG_Worlds.uproject"

// Build config:
IWYU: ON  ·  Warnings-as-errors: WCGASCore
Unity builds: OFF (complex modules)

New Module Checklist

Every new planned module follows this exact sequence. The creator built 10 modules this way — consistency is what makes the plugin coherent.

WCAudioSuite — First Build Reference

Implementation order inside WCAudioSuite

Build in this sequence so you always have something compilable:

1. WCAudioSuite.h + WCAudioSuite.Build.cs + WCAudioSettings.h  // module compiles
2. WCMusicTypes.h + WCMusicStateDefinition.h + WCMusicLayerDefinition.h  // data assets
3. UWCAudioSubsystem.h/.cpp  // world subsystem, stub implementations
4. UWCMusicDirectorComponent.h/.cpp  // tag watching, calls subsystem
5. Wire into DynamicRPGWorlds: AWCHUD creates MusicDirectorComponent  // playable
6. UWCAmbientZoneDefinition + AWCAmbientZoneVolume  // ambient zones
7. UWCCombatAudioDefinition + UWCStingerDefinition  // combat audio
8. WCDynamicSociety calendar integration  // day/night ambient switch