Skip to content

Interface System

Summary: Project Eternal uses interface-driven design for cross-system communication. Core interfaces enable loose coupling between combat, animation, targeting, and effects systems, allowing systems to interact through contracts rather than direct references.

Table of Contents


Why Interfaces

The Coupling Problem

Without interfaces, systems become tightly coupled:

+------------------------------------------------------------------+
|                    WITHOUT INTERFACES                             |
+------------------------------------------------------------------+
|                                                                  |
|   Ability System                                                 |
|       |                                                          |
|       +-- Needs direct reference to UCombatComponent             |
|       +-- Needs direct reference to UPoiseSystemComponent        |
|       +-- Needs direct reference to UMontageManagerComponent     |
|       +-- Needs direct reference to UCombatEffectsManager        |
|                                                                  |
|   Problem: Any change to these components breaks abilities       |
|                                                                  |
+------------------------------------------------------------------+

The Interface Solution

+------------------------------------------------------------------+
|                    WITH INTERFACES                                |
+------------------------------------------------------------------+
|                                                                  |
|   Ability System                                                 |
|       |                                                          |
|       +-- Uses ICombatInterface                                  |
|       +-- Uses IPoiseSystemInterface                             |
|       +-- Uses IMontageManagerInterface                          |
|       +-- Uses ICombatEffectsInterface                           |
|                                                                  |
|   Benefits:                                                      |
|   - Components can change internals without breaking abilities   |
|   - New character types just implement interfaces                |
|   - Easy to mock for testing                                     |
|   - Clear contracts for network validation                       |
|                                                                  |
+------------------------------------------------------------------+

Design Benefits

Benefit How It's Achieved
Abstraction Systems talk via contracts, not implementations
Modularity Components can be replaced without changing callers
Extensibility New character types only need to implement interfaces
Testability Interfaces enable mocking for unit tests
Multiplayer Clear boundaries for network validation

Core Interfaces

Interface Overview

+------------------------------------------------------------------+
|                    CORE INTERFACES                                |
+------------------------------------------------------------------+
|                                                                  |
|   Location: Source/ProjectEternal/Public/Interface/              |
|                                                                  |
|   +-------------------+    +-------------------------+           |
|   | ICombatInterface  |    | IMontageManagerInterface|           |
|   | - GetCombatComp   |    | - GetMontageByTag       |           |
|   | - GetHitDirection |    | - GetHitReactMontage    |           |
|   +-------------------+    +-------------------------+           |
|                                                                  |
|   +-------------------+    +-------------------------+           |
|   | ITargetable       |    | IPoiseSystemInterface   |           |
|   | - IsValid         |    | - ApplyPoiseDamage      |           |
|   | - CanAttack       |    | - GetPoisePercentage    |           |
|   | - IsFriendly      |    | - CanAct                |           |
|   +-------------------+    +-------------------------+           |
|                                                                  |
|   +-------------------+    +-------------------------+           |
|   | ICombatEffects    |    | IEquipmentOwner         |           |
|   | - TriggerEffect   |    | - GetEquipmentComponent |           |
|   | - TriggerHitStop  |    +-------------------------+           |
|   +-------------------+                                          |
|                                                                  |
|   +-------------------+    +-------------------------+           |
|   | IPlayerInventory  |    | IQuestParticipant       |           |
|   | - GetInventoryComp|    | - GetPlayerQuestComp    |           |
|   +-------------------+    +-------------------------+           |
|                                                                  |
+------------------------------------------------------------------+

ICombatInterface

Provides access to combat state and hit direction calculations.

Method Return Type Purpose
GetCombatComponent() UCombatComponent* Access to combat component
GetPlayerCombatComponent() UPlayerCombatComponent* Player-specific combat
GetEnemyCombatComponent() UEnemyCombatComponent* Enemy-specific combat
GetHitDirection() EHitDirection Direction of incoming hit

Hit Direction Values:

Value Meaning
Front Hit from character's front
Back Hit from behind
Left Hit from left side
Right Hit from right side
None No directional hit

Implementers: AEternalCharacter

IMontageManagerInterface

Manages animation montage lookup by gameplay tag.

Method Return Type Purpose
GetMontageByTag() UAnimMontage* Look up montage by action tag
GetHitReactMontage() UAnimMontage* Get hit reaction for direction
GetDefaultMontageTable() UDataTable* Get the default montage data table

Implementers: AEternalCharacter, UMontageManagerComponent

ITargetable

Targeting system validation interface.

Method Return Type Purpose
GetTarget() AActor* Get the target actor
GetTargetsTarget() AActor* Get what this target is targeting
IsValid() bool Can this actor be targeted?
CanAttack() bool Is this actor able to attack?
IsFriendly() bool Is this actor friendly to the caller?

Implementers: AEternalCharacter

IPoiseSystemInterface

Poise/stagger system abstraction.

Method Return Type Purpose
ApplyPoiseDamage() bool Apply poise damage to actor
GetPoisePercentage() float Current poise as 0-1 value
CanAct() bool Is actor able to take actions?

Poise States:

State Description
Stable Normal operation
Weakened Low poise, vulnerable
Staggered Briefly stunned
Broken Extended stun state
Recovering Legacy — no longer entered. Retained in the enum for replication and Blueprint compatibility

Implementers: UPoiseSystemComponent

ICombatEffectsInterface

Visual and audio effects trigger interface.

Method Return Type Purpose
TriggerEffectByTag() void Trigger VFX/audio by tag
TriggerHitStop() void Freeze-frame effect on hit
TriggerSlowMotion() void Time dilation effect

Implementers: UCombatEffectsManager

IEquipmentOwner

Interface for actors that own equipment. Provides decoupled access to equipment without casting to concrete types.

Method Return Type Purpose
GetEquipmentComponent() UEquipmentComponent* Access to equipment component

Implementers: AEternalPlayer (PlayerController)

Why this interface exists: - Equipment lives on PlayerController (persists across death) - Other systems (abilities, UI) need equipment access - Avoids casting to AEternalPlayer throughout the codebase - Enables testing with mock equipment owners

IPlayerInventory

Interface for actors that manage player inventory.

Method Return Type Purpose
GetInventoryComponent() UInventoryComponent* Access to inventory component

Implementers: AEternalPlayerState

Note: PlayerState implements this interface but delegates to PlayerController, which owns the actual InventoryComponent. This allows systems to query inventory via PlayerState (which replicates) while the component lives on Controller (which persists).

IQuestParticipant

Interface for actors participating in the quest system.

Method Return Type Purpose
GetPlayerQuestComponent() UPlayerQuestComponent* Access to quest tracking

Implementers: AEternalPlayerState, AEternalNPC

IDlgDialogueParticipant

Interface for actors participating in dialogue system interactions.

Method Return Type Purpose
GetDialogueParticipantName() FString Get actor's dialogue display name
OnDialogueStarted() void Called when dialogue begins
OnDialogueEnded() void Called when dialogue concludes

Implementers: AEternalNPC

ICombatDataProvider

Provides combat data to sub-components (UComboComponent, UChargeComponent), replacing fragile TFunction callbacks with a stable interface contract.

Method Return Type Purpose
GetCurrentWeaponFragment() const FWeaponFragment* Current weapon fragment (or unarmed fallback)
GetActiveWeaponMesh() USkeletalMeshComponent* Active weapon mesh (character mesh if unarmed)
GetCombatMontagesTable() UDataTable* Combat montages table for the current weapon
IsUnarmed() bool Is the player currently unarmed?
GetUnarmedWeaponFragment() const FWeaponFragment* Default combat stats when no weapon equipped
GetCurrentWeaponHand() FGameplayTag Weapon hand tag for hand-aware combo/charge/montage resolution — the charge component resolves its per-weapon config through it too

Implementers: UPlayerCombatComponent

Note: C++-only interface (no UFUNCTIONs) because it returns pointers to non-UObject types (FWeaponFragment) which cannot be exposed to Blueprint.

IItemContainer

Unified contract for any container holding items in a spatial grid (inventory, stash, vendor, loot piles), so callers never need the concrete container type. All methods are BlueprintNativeEvent and called via the Execute_ pattern.

Item operations:

Method Return Type Purpose
TryAddItemToContainer() bool Primary add method — stacking, space checks, server authority
PlaceItemAtIndex() bool Place item at a specific grid index (handles authority/replication)
AddItemAtPosition() bool Add item at a top-left grid position
TryPlaceItemViaRegistry() bool Centralized, registry-aware placement usable by any caller
CanAddItemAt() bool Can the item be placed at this position?
RemoveItemFromContainer() bool Remove an item
FindItemInContainer() UItemObject* Find first item matching a FPrimaryAssetId
GetAllItemsInContainer() TArray<UItemObject*> All items in the container
HasItemInContainer() bool Does the container hold this item?

Grid operations:

Method Return Type Purpose
GetContainerWidth() / GetContainerHeight() int32 Grid dimensions
IndexToCoordinates() / CoordinatesToIndex() FIntPoint / int32 Flattened index <-> 2D coordinate conversion
IsValidIndex() bool Is the index within grid bounds?
IsSpaceAvailable() bool Is a rectangular space free (with optional ignore items for swaps)?
FindAvailableSpace() bool Find first free space for given item dimensions

Implementers: UItemContainerComponent (and its subclasses UInventoryComponent, UVendorContainerComponent, UCraftingContainerComponent)

Usage Patterns

Pattern 1: Cast and Execute

The standard pattern for interface calls:

Check interface --> Execute method
      |                  |
      v                  v
ImplementsInterface()   Execute_MethodName(Actor, Params)
Step What Happens
1 Check if actor implements interface
2 Use Execute_ prefix to call method
3 Pass actor as first parameter

Pattern 2: Interface with Fallback

When you need to support both interface and direct component access:

Try interface cast --> If fails --> Find component directly
       |                                    |
       v                                    v
Cast<IInterface>()              FindComponentByClass<T>()

Pattern 3: Interface Delegation

Parent class implements interface, delegates to component:

Actor implements IInterface
       |
       v
Interface method calls component
       |
       v
Component contains actual logic

Why delegate? - Actors expose component functionality - Components contain actual implementation - Clean separation of concerns

Pattern 4: Multiple Interface Composition

Single class implements multiple interfaces:

AEternalCharacter
    |
    +-- IAbilitySystemInterface   (GAS integration)
    +-- ICombatInterface          (Combat access)
    +-- IMontageManagerInterface  (Animation management)
    +-- ITargetable               (Targeting system)

Benefits: - One class serves multiple systems - Systems interact through interfaces - Easy to extend with new interfaces


Cross-System Communication

Combat to Poise Flow

+------------------------------------------------------------------+
|                    COMBAT --> POISE FLOW                          |
+------------------------------------------------------------------+
|                                                                  |
|   Ability (EternalMeleeAttack)                                   |
|           |                                                      |
|           v                                                      |
|   Cast<IPoiseSystemInterface>(TargetActor)                       |
|           |                                                      |
|           v                                                      |
|   Execute_ApplyPoiseDamage(Target, Damage, Source)               |
|           |                                                      |
|           v                                                      |
|   UPoiseSystemComponent receives damage                          |
|           |                                                      |
|           v                                                      |
|   Applies GAS effect to Poise attribute                          |
|           |                                                      |
|           v                                                      |
|   Updates EPoiseState (may become Staggered/Broken)              |
|           |                                                      |
|           v                                                      |
|   Broadcasts OnPoiseStateChangedDelegate                         |
|           |                                                      |
|           v                                                      |
|   Ability/UI reacts to state change                              |
|                                                                  |
+------------------------------------------------------------------+

Ability to Animation Flow

+------------------------------------------------------------------+
|                    ABILITY --> ANIMATION FLOW                     |
+------------------------------------------------------------------+
|                                                                  |
|   Ability requests montage                                       |
|           |                                                      |
|           v                                                      |
|   GetAvatarActor as IMontageManagerInterface                     |
|           |                                                      |
|           v                                                      |
|   GetMontageByTag(ActionTag, Index, Table)                       |
|           |                                                      |
|           v                                                      |
|   MontageManagerComponent looks up DataTable                     |
|           |                                                      |
|           v                                                      |
|   Returns UAnimMontage*                                          |
|           |                                                      |
|           v                                                      |
|   Ability plays montage via ASC                                  |
|                                                                  |
+------------------------------------------------------------------+

Targeting Validation Flow

+------------------------------------------------------------------+
|                    TARGETING VALIDATION                           |
+------------------------------------------------------------------+
|                                                                  |
|   TargetingComponent finds potential targets                     |
|           |                                                      |
|           v                                                      |
|   For each potential target:                                     |
|           |                                                      |
|           v                                                      |
|   Checks: ImplementsInterface(UTargetable)                       |
|           |                                                      |
|           v                                                      |
|   Calls: Execute_IsValid(Pawn, AllowSelf, Controller)            |
|           |                                                      |
|           v                                                      |
|   Character validates itself (alive, not invisible, etc)         |
|           |                                                      |
|           v                                                      |
|   Returns true/false                                             |
|           |                                                      |
|           v                                                      |
|   TargetingComponent builds filtered list                        |
|                                                                  |
+------------------------------------------------------------------+

Source Reference

Topic File Symbol
Combat Interface Source/ProjectEternal/Public/Interface/CombatInterface.h ICombatInterface
Montage Manager Interface Source/ProjectEternal/Public/Interface/MontageManagerInterface.h IMontageManagerInterface
Targetable Interface Source/ProjectEternal/Public/Interface/ITargetable.h ITargetable
Poise System Interface Source/ProjectEternal/Public/Interface/PoiseSystemInterface.h IPoiseSystemInterface, EPoiseState
Combat Effects Interface Source/ProjectEternal/Public/Interface/CombatEffectsInterface.h ICombatEffectsInterface
Equipment Owner Interface Source/ProjectEternal/Public/Interface/EquipmentOwnerInterface.h IEquipmentOwner
Player Inventory Interface Source/ProjectEternal/Public/Inventory/Interfaces/PlayerInventory.h IPlayerInventory
Dialogue Participant Interface Plugins/DlgSystem/Source/DlgSystem/DlgDialogueParticipant.h IDlgDialogueParticipant
Combat Data Provider Interface Source/ProjectEternal/Public/Interface/CombatDataProviderInterface.h ICombatDataProvider
Item Container Interface Source/ProjectEternal/Public/Inventory/Interfaces/ItemContainer.h IItemContainer
Quest Participant Interface Source/ProjectEternal/Public/Quest/Interfaces/QuestParticipant.h IQuestParticipant
Character Implementation Source/ProjectEternal/Private/Character/EternalCharacter.cpp AEternalCharacter interface overrides
Poise Component Source/ProjectEternal/Private/Combat/Components/PoiseSystemComponent.cpp UPoiseSystemComponent
Combat Effects Manager Source/ProjectEternal/Private/Combat/Components/CombatEffectsManager.cpp UCombatEffectsManager


Recent Changes

Date Change Impact
2026-08-06 Marked EPoiseState::Recovering as legacy (no longer entered, kept for replication/Blueprint compatibility); noted that GetCurrentWeaponHand() also resolves per-weapon charge configuration; replaced the invented line ranges in the source reference table with symbol anchors Readers stop treating Recovering as a live state, and the reference table no longer points at line numbers that never matched the files
2026-07-03 Documented ICombatDataProvider, IItemContainer Complete interface reference for combat data and item container contracts
2026-01-19 Added IDlgDialogueParticipant interface; AEternalNPC now implements dialogue system Dialogue system integration
2025-12-28 Added IEquipmentOwner interface Equipment access without concrete casts
2025-12-28 Documented IPlayerInventory, IQuestParticipant Complete interface reference
- Initial documentation -