# API Reference

> The C++ and Blueprint surface: the controller components, the combat token subsystem, the melee trace pipeline, territory lookups, and the scorer and gate bases.

Markdown version of https://rigbak.com/docs/soulslike-combat/api-reference, a page of the Soulslike Enemy Combat documentation. Link that page when citing it.

The classes and their public members. For building an enemy, start with [Getting Started](https://rigbak.com/docs/soulslike-combat/getting-started); this page is the reference you reach for when extending the system in C++. Each system's own page covers the same ground for Blueprint.

---

## SECCombatControllerComponent

The hub every setup needs. Add it to any `AAIController` and the combat system works. It resolves the AI config, registers combat roles, syncs role-based state, and orchestrates death.

> **Note**
>
> To read the config or role from outside the component, call the static helpers instead of casting to `AEnemyControllerBase`. They work on any controller carrying the component.

**Static helpers**

| Function | Returns |
| --- | --- |
| `ResolveAIConfig(Controller)` | The controller's cached config, or the pawn's config via `IEnemyAIConfigProvider`, or null |
| `ResolveCurrentCombatRole(Controller)` | The current combat role tag, or an empty tag |

**Instance accessors**

| Function | Returns |
| --- | --- |
| `GetCachedAIConfig()` | The resolved `UEnemyAIConfig` in use |
| `GetCurrentCombatRole()` | The current combat role tag |

**Overridable hooks** (`BlueprintNativeEvent`, call the parent to keep default behavior)

| Function | Purpose |
| --- | --- |
| `SyncStateForCombatRole(RoleTag)` | Runs when the role changes. Override to swap animation sets, trigger effects, or switch StateTree assets. Call Super to keep the action set, reaction set, weapon set and movement profile sync. |
| `HandleCombatTargetLost(LostTarget)` | Runs when the target is destroyed or unregistered. Override for fallback behavior (patrol, switch aggro). The default broadcasts `OnCombatTargetLost`. |

**Blueprint-callable**

| Function | Purpose |
| --- | --- |
| `ApplyLocalCombatRole(RoleTag)` | Adopt a role locally without registering with the subsystem. Syncs the action set and movement profile like a subsystem-assigned role, but consumes no slots and joins no coordination. For bosses and solo enemies. |
| `HandleDeath()` | Full SEC shutdown, idempotent. Cancels the in-flight action and reaction, stops the brain, stops melee tracing, disables threat detection, unregisters from the role subsystem, clears focus, then broadcasts `OnDeath`. Does not unpossess or destroy the pawn. |
| `HandleRevive()` | Brings a dead enemy back under AI control: releases the action block death took, restarts the brain, and turns threat detection, perception and role registration back on, then broadcasts `OnRevive`. Call it on a revive or when a pooled enemy is reused. A controller that died stays blocked from acting until it runs. The weapon death unequipped is not re-equipped, and perception returns only when the AI Config manages it. |

**Properties**

| Property | Default | Purpose |
| --- | --- | --- |
| `DefaultAIConfig` | null | Fallback config when the pawn provides none via `IEnemyAIConfigProvider` |
| `bAutoRegisterForCombatRoles` | true | Register with the combat role subsystem on possession |
| `RoleRegistrationParams` | n/a | Registration parameters used when the pawn has no config |
| `bEnableThreatDetection` | true | Enable threat detection on BeginPlay when a `ThreatDetectionComponent` is present |
| `bAutoHandleDeathOnHealthDepleted` | true | Call `HandleDeath()` automatically when the pawn's [health vital](https://rigbak.com/docs/soulslike-combat/vitals) empties |
| `bDropWeaponOnDeath` | true | Release everything the pawn holds with `Drop` on death, which asks each item to drop itself and carries the equipment component's `DropLifetime` as the suggested lifespan. Off releases with `LeaveInWorld` |

**Delegates**

| Delegate | Fires |
| --- | --- |
| `OnCombatRoleChanged(NewRole, OldRole)` | When the role changes, from subsystem assignment or local apply |
| `OnCombatTargetLost(LostTarget)` | When the target is destroyed or unregistered |
| `OnCombatRoleSystemReady(Controller)` | After registration with the role subsystem. Safe to read the initial role here |
| `OnDeath()` | At the end of `HandleDeath()`, once every system is stopped. Safe to ragdoll, spawn VFX, or destroy |
| `OnRevive()` | At the end of `HandleRevive()`, once every system is running again |

---

## EnemyControllerBase

The convenience controller. It creates every combat component as a default subobject and adds facing and rotation behavior on top of `SECCombatControllerComponent`.

**Rotation lock** (freezes facing during a committed attack)

| Function | Purpose |
| --- | --- |
| `LockRotationBy(LockOwner)` | Hold a rotation lock keyed to an owner. Releases when the owner is destroyed, or when an `InstancedPerActor` ability goes inactive. Defaults to the caller. |
| `UnlockRotationBy(LockOwner)` | Release that owner's lock |
| `LockRotation()` / `UnlockRotation()` | Keyless counter-based lock; balance each call |
| `ForceUnlockRotation()` | Clear both the counter and the owner set |
| `IsRotationLocked()` | True while any lock holds |

`UGameplayAbilityBase` locks rotation through this API when `bLockAIRotation` is set, so montage-driven attacks commit without extra wiring.

**Facing**

| Member | Default | Purpose |
| --- | --- | --- |
| `GetDesiredFacingLocation(OutLocation)` | n/a | `BlueprintNativeEvent` returning the world location to face. Override for custom facing |
| `SmoothFocusInterpSpeed` | 165.0 | Interpolation speed for smooth focus rotation |
| `bFaceLastKnownWhenNotDetected` | true | Track the live target only while Detected; otherwise face its last-known location instead of through walls |

**Team**

| Member | Purpose |
| --- | --- |
| `USECTeamComponent` | Holds the team on the possessed pawn: `TeamId` (0 = player, 1 = enemy, 255 = neutral), Free-For-All, and the exclusion rules |
| `IGenericTeamAgentInterface` | Answers AI Perception and EQS by reading that component |

**Blueprint events** (forwarded from the combat component)

| Event | Fires |
| --- | --- |
| `K2_OnCombatRoleAssigned(NewRole, OldRole)` | On role assignment |
| `K2_OnCombatTargetLost(LostTarget)` | When the target is lost |
| `K2_OnReactionSetApplied(RoleTag, ReactionSet)` | When a reaction set is applied via role sync |
| `K2_OnDeath()` | After `HandleDeath()` completes; safe to ragdoll or play a death montage |

`HandleDeath()` on the controller is a convenience wrapper around the component's `HandleDeath()`. Component accessors: `GetCombatControllerComponent`, `GetHelperBTComponent`, `GetReactionEvaluationComponent`, `GetAwarenessComponent`. Delegates: `OnFocusSet`, `OnFocusCleared` (fires only when there was a focus to clear), `OnActionStateChanged`.

---

## SECBrainComponent

Chooses how the AI runs from its config: a StateTree when one is named, otherwise a native C++ combat loop.

| Member | Default | Purpose |
| --- | --- | --- |
| `RefreshBrain()` | n/a | Re-evaluate the config and switch brains if the StateTree choice changed. Call after changing the config at runtime without re-possessing |
| `IsRunningNativeBrain()` | n/a | True while the native loop drives the AI |
| `EvaluationCooldown` | 0.1 | Seconds between action evaluations in the native loop |

In native mode the component holds the controller's brain slot, so `HandleDeath` stops it and the per-action behavior-tree swap restores it.

---

## BotStateTreeAIComponent

Extends Unreal's `UStateTreeAIComponent`. `SECBrainComponent` creates it at runtime when the config names a StateTree. It resolves the config on possession in this order:

1. The controller's `SECCombatControllerComponent` cached config
2. A pawn implementing `IEnemyAIConfigProvider`
3. The `FallbackStateTree` on this component

| Member | Default | Purpose |
| --- | --- | --- |
| `InitializeFromAIConfig(AIConfig)` | n/a | Set and start the config's `StateTree`. Returns true on success |
| `AddLinkedStateTreeOverride(StateTag, StateTreeReference)` | n/a | Swap a sub-tree per gameplay tag, for enemy variants |
| `bAutoInitializeFromConfig` | true | Initialize from the config automatically on possession. Disable for manual control |
| `FallbackStateTree` | null | Used when no config is found or the config names no StateTree |

---

## USECCombatTokenSubsystem

The world subsystem holding the permission slots each target hands out. Server only: every function that changes the ledger returns without effect on a client, and the queries there report no block. See [Combat Tokens](https://rigbak.com/docs/soulslike-combat/combat-tokens).

**Claiming**

```cpp
bool  TryClaimTokens(AActor* Target, AController* Holder, const TArray<FSECTokenRequirement>& Requirements, FSECTokenLeaseHandle& OutLease);
void  ReleaseTokens(const FSECTokenLeaseHandle& Lease);
int32 ReleaseAllTokensForHolder(AController* Holder);
bool  CanClaimToken(AActor* Target, AController* Holder, FGameplayTag TokenTag, int32 Cost = 1) const;
bool  HoldsToken(AActor* Target, AController* Holder, FGameplayTag TokenTag) const;
```

`TryClaimTokens` takes every listed slot or takes none. `ReleaseTokens` hands back what one receipt covers and starts the reissue delay; running it twice, or with a receipt for a target that is gone, does nothing. `ReleaseAllTokensForHolder` reports how many claims it freed. `CanClaimToken` reserves nothing and reads true while the holder already holds a slot for the tag.

**Budget and query**: `SetTokenBudget`, `ClearTokenBudget`, `ClearTarget`, `GetTokenBudget`, `GetAvailableTokens`, `GetTokenHolders`, `IsTokenTarget`, `GetTokenPoolStatus`. `OnTokenAvailabilityChanged(Target, TokenTag, AvailableTokens, Budget)` fires when a pool's free count moves.

| Struct | Members |
| --- | --- |
| `FSECTokenRequirement` | `TokenTag`, `Cost` (1). Two entries naming one tag keep the larger cost |
| `FSECTokenLeaseHandle` | `ClaimId` (0 means nothing is held), `Target`. The target rides on the receipt so a release finds the right pool after the AI has moved on |
| `FSECTokenPoolStatus` | `TokenTag`, `Budget`, `AvailableTokens`, `HeldTokens`, `CoolingTokens`, `SecondsUntilNextReissue`, `Holders` |

A holder destroyed without releasing frees its slot the next time the pool is read, so an AI that has gone cannot hold a pool shut.

**USECTokenGate**

```cpp
static void CollectRequirements(const FSECCustomScoring& Scoring, TArray<FSECTokenRequirement>& OutRequirements);
```

Gathers what a spec's token gates need, merging duplicate tags and skipping inverted gates. `UActionEvaluationComponent` calls it as an action starts and claims against the controller's focus actor, the same actor the gate scored against.

---

## USECScorer and USECGate

The two bases an action or reaction extends its scoring with, both `Blueprintable` and `EditInlineNew`. Instances live in `FSECCustomScoring`: `Scorers` for soft multipliers, `Gates` for hard vetoes. See [Action System](https://rigbak.com/docs/soulslike-combat/action-system).

```cpp
virtual float ScoreMultiplier_Implementation(const FSECScoringContext& Context) const;  // USECScorer, 1.0 = no effect
virtual bool  PassesGate_Implementation(const FSECScoringContext& Context) const;       // USECGate, false vetoes
virtual FString GetDisplayName_Implementation() const;                                  // row title, logs, breakdown
```

Subclasses must be stateless: one instance is shared across every AI using the asset. Derive randomness from `SeededRandom(Context)` rather than raw RNG.

`FSECScoringContext` carries `Controller`, `Target`, `ASC`, `SpecId`, `EventTag`, `Surface`, `Seed`, `WindowId`, the snapshot fields `Distance`, `AngleDegAbs`, `Speed`, `HealthPercentage`, `Stamina`, the `Vitals` component, and the `Stimulus` that set a reaction off. It carries no threat figure, so a scorer wanting camera attention reads `UThreatDetectionComponent::GetCurrentThreatLevel()` off `Context.Controller`.

`Surface` names the list the scorer is running in (`Actions`, `Reactions`, `TriggerRules`). One class serves all three, and branches on this where the difference matters.

---

## USECMeleeTraceComponent

The swept-trace component on the pawn. Five phases of its pipeline are `BlueprintNativeEvent`, so a Blueprint subclass overrides the event and a C++ subclass overrides `_Implementation`. See [Melee Trace](https://rigbak.com/docs/soulslike-combat/melee-trace).

```cpp
FSECDamageInfo         BuildDamageInfo(AActor* HitActor, const FHitResult& Hit, const FVector& Direction, const FSECTraceSocket& Socket) const;
void                   HandleDamageResult(AActor* HitActor, const FSECMeleeHitData& MeleeHitData, const FSECDamageResult& Result);
ESECHitClassification  ClassifyHit(AActor* HitActor, const FHitResult& Hit) const;
ESECContactRole        ClassifyContact(AActor* HitActor, const FHitResult& Hit) const;
bool                   ShouldDetectHits() const;
```

`ShouldDetectHits` answers the authority. `HandleDamageResult` replaces the recording rule outright, so call `RecordHit` for the hits an override means to keep. `CanHitActor`, `RecordHit` and `IsPassThroughTarget` are protected, so an override reaches them from the subclass. `GetTargetsHitThisWindow` is public, for damage falloff across a cleave. `BuildSweepQueryParams(FCollisionQueryParams&)` is C++ only, for a sweep that asks the world something else, such as complex collision to read the struck face's material.

Manual control, for a project not driving traces from a montage:

```cpp
virtual void StartTracing(const TArray<FName>& SocketIDs, USECDamageConfig* DamageConfig = nullptr, bool bDebugOverride = false);
virtual void StartTracingSimple(const TArray<FName>& SocketIDs, float DamageOverride);
virtual void StopTracing();

bool RegisterTraceSocket_Struct(const FSECTraceSocket& TraceSocket);
void UnregisterTraceSocket(FName ID);
bool UnregisterTraceSocketFrom(FName ID, const USceneComponent* ExpectedSource);
void UnregisterAllSockets();

TArray<FName>   GetRegisteredSocketIDs() const;
void            AddTraceIgnoredActor(AActor* Actor);
void            RemoveTraceIgnoredActor(AActor* Actor);
TArray<AActor*> GetTraceIgnoredActors() const;
```

`StartTracingSimple` takes a numeric override instead of a config; a value below zero falls back to `BaseDamage`. `RegisterTraceSocket_Struct` is the only entry point reading `SourceComponentTag` and a socket's own filter override, and returns false when the socket has no ID, names no source, or another component holds its ID. It accepts a socket on every machine, since which machine sweeps can change after the weapon is drawn, so a socket that registered says nothing about whether this machine sweeps.

**Windows and delivery**, for a C++ subclass:

```cpp
virtual bool OpenWindow(const FSECTraceWindowRequest& Request);
virtual void CloseWindow();
virtual bool KeepsSweepingAfterEnd(float SecondsSinceEnd) const;   // false by default
virtual void DeliverHit(const FSECTraceWindowState& Window, const FSECMeleeHitData& HitData, const FSECTraceSocket& Socket);
void         ResolveHit(const FSECTraceWindowState& Window, const FSECMeleeHitData& HitData, const FSECTraceSocket& Socket, bool bSweptHere);
static bool  IsTriggerContact(const FHitResult& Hit);   // BlueprintPure
```

`OpenWindow` opens the window every start asks for, closing any still open, and is refused on a machine that does not detect hits or for a request that leaves no registered socket to sweep. Override it and `CloseWindow`, calling `Super`, for work that follows the window; an override of `StartTracing`, the two tagged starts, `StartTracingSimple` or `StopTracing` still hears every window, a montage window's included. `KeepsSweepingAfterEnd` lets a window sweep on past its end while its montage play runs, for sockets that read a drawn pose reaching the end of a swing later than the animation does. `DeliverHit` turns one swept hit into damage, resolving it on this machine by default; a subclass that carries hits to another machine overrides it and calls `ResolveHit` where the hit lands. `IsTriggerContact` answers whether a hit reached a trigger volume, so a Blueprint override of `ClassifyContact` keeps that rule beside its own.

`SECMontageWindow::IsPlaying(Window)` answers whether the montage play a window belongs to still runs on its mesh, wherever playback sits.

**ISECPhysicsImpulseReceiver** is C++ only. A component implementing it on the struck actor takes the push from **SEC Apply Physics Impulse** through `ReceivePhysicsImpulse(UPrimitiveComponent& Component, const FSECPhysicsImpulse& Impulse)` and reports whether it drives that component, which a project driving a ragdoll on every machine uses to hand the push to each copy of the body. Without one, the effect pushes the body itself.

**Payloads**

| Struct | Members |
| --- | --- |
| `FSECMeleeHitData` | `HitResult`, `FromSocketID`, `DamageConfig`, `Classification`. Carried by `OnMeleeHit` and `OnMeleeSensed` |
| `FSECDamageResult` | `DamageApplied`, `AdditionalVitalDamageApplied`, `bWasFatal`, `ResultTags`. Added by `OnMeleeHitResponse` |
| `FSECDamageInfo` | `Instigator`, `DamageCauser` (the weapon when the socket sits on one, the wielder otherwise), `HitResult`, `HitDirection`, `DamageDefinition`, `DamageConfig`, `DamageTags`, `CustomPayload` |

A target reached through point damage reports what its `TakeDamage` returned, with no fatal flag and no result tags. Subclass `USECDamageConfig` to carry per-attack data of your own and cast it inside the target's `HandleIncomingDamage`.

---

## USECApproachComponent

Steers an attack across its approach window. [Animation Integration](https://rigbak.com/docs/soulslike-combat/animation-integration#steer-an-attack-toward-its-target) covers it for Blueprint; C++ alone reaches these:

```cpp
void HoldDestinationOverride(const UObject* Holder, const FTransform& Destination, ESECApproachSpeedLimit InSpeedLimit, float InMaxApproachSpeed);
void ReleaseDestinationOverride(const UObject* Holder);
```

`HoldDestinationOverride` sends every approach window that opens while `Holder` holds it to `Destination` instead of the target its named slot stores, at that speed limit unless the window names its own, for a character another system places, such as a scripted sequence putting it on its mark. Holding again replaces the spot, and only the same holder's release gives the windows their named targets back. A Move by Offset window keeps its own offset.

`bGliding` and `GlideVelocity`, both Blueprint read-only, report whether a window is sliding the character across the ground and how fast, in cm/s. They settle once a frame, so every reader that frame gets the same answer.

**USECAbilityTask_ApproachGlide**

```cpp
static USECAbilityTask_ApproachGlide* ApproachGlide(UGameplayAbility* OwningAbility, FName TaskInstanceName, AActor* Followed, const FVector& Destination, float StopDistance, float MaxSpeed, float LeadStrength, float Duration, UCurveFloat* TimeMappingCurve, float SecondsRun = 0.0f);
```

Glides the character through an ability for `Duration` seconds, toward `Followed`, worked out again every frame, or to `Destination` when there is none. `StopDistance` already counts both capsules; a negative `MaxSpeed` covers the distance over the duration instead; `LeadStrength` runs from 0 to 1 for how much of the followed actor's motion the goal leads. The glide runs wherever its ability runs, predicted on the owning client when the ability predicts, and other players' machines see it through the character's replicated movement.

**SECApproachMath**

| Function | Returns |
| --- | --- |
| `StopDistanceBetween(Mover, Target, StopDistance)` | How far apart two characters end up, center to center, when a glide stops `StopDistance` short of the target: the stop distance plus both capsules' radii |
| `BrakingDistance(Speed, BrakingDeceleration, Friction)` | How far a character moving at `Speed` slides before its own braking stops it, in cm |
| `RestArrivalRadius(ArrivalRadius, MaxSpeed)` | How far from its spot a walk until arrival still counts as arrived when the server sees a remote player come to rest: `ArrivalRadius` plus the ground `MaxSpeed` covers in 0.3 s |

---

## USECMovementModifierComponent

**SEC Movement Modifiers**, the one place a character's walk speed, acceleration, braking, ground friction, turn rate and turning flags change from. [Animation Integration](https://rigbak.com/docs/soulslike-combat/animation-integration#changing-movement-from-your-own-blueprint) covers it for Blueprint.

```cpp
static USECMovementModifierComponent* FindOrAdd(AActor* Actor);   // Blueprint: Get Movement Modifiers
static USECMovementModifierComponent* Find(const AActor* Actor);

void  OverrideValue(const UObject* Source, ESECMovementValue Value, float NewValue, int32 Priority = 100);
void  ScaleValue(const UObject* Source, ESECMovementValue Value, float Scale);
void  OverrideFlag(const UObject* Source, ESECMovementFlag Flag, bool bNewValue, int32 Priority = 100);
bool  RemoveValueModifier(const UObject* Source, ESECMovementValue Value);
bool  RemoveFlagOverride(const UObject* Source, ESECMovementFlag Flag);
int32 RemoveModifiers(const UObject* Source);

float GetValue(ESECMovementValue Value) const;
bool  GetFlag(ESECMovementFlag Flag) const;
float GetBaseValue(ESECMovementValue Value) const;
void  SetBaseValue(ESECMovementValue Value, float NewBase);
```

`FindOrAdd` adds the component the first time it is asked and answers null for an actor that is not a pawn or is being torn down; `Find` answers null while nothing has changed the character's movement. Three constants name the priority levels: `PacePriority` (0) for a pace the character sets for itself, `StylePriority` (100) for the settings a whole style of play makes and the default for a Blueprint override, and `FacingPriority` (1000) for a hold on the facing, which an approach window takes.

## USECTerritoryComponent

Pawn-side, server only. The route, ground and leash functions are Blueprint exposed and covered on [Territory & Patrols](https://rigbak.com/docs/soulslike-combat/territory). The lookups, and the two members C++ alone reaches:

| Function | Purpose |
| --- | --- |
| `static USECTerritoryComponent* FindTerritoryComponent(const AController* Controller)` | The component on a controller or its possessed pawn |
| `static FVector GetPostLocationFor(AActor* Post)` | Where a post stands, for any actor, post component or not |
| `static float GetWanderExtentFor(AActor* Post)` | How far an enemy may drift from a post, 0 for an actor with no post component |
| `static int32 StepPostIndex(ESECPostOrder Order, int32 PostCount, int32 CurrentIndex, int32& InOutPingPongStep)` | The next index an order policy names, with no reference to where the pawn is. C++ only; `AdvanceRoute` is the Blueprint-reachable form |
| `float GetLeashSlack() const` | `LeashRadius` as a usable number: never negative, and 0 when it is not a real number |

**USECTerritoryPostComponent**

`static USECTerritoryPostComponent* FindPostComponent(const AActor* PostActor)` resolves the post component from any actor, and reads null for one carrying none.

```cpp
virtual bool PickPointInArea_Implementation(const AActor* Querier, FVector& OutPoint) const;
```

Override it for a post that works its destination out at runtime. `Querier` is the pawn being sent there, which sizes the navmesh query to its agent; returning false stands the enemy on the post itself. The base gathers reachable spots inside the area, up to `PointSampleAttempts` tries, and picks among them under `WanderSelection`.

---

## Deprecated, removed in 4.0

Each item below keeps working until 4.0, and its deprecation message names the replacement. A Blueprint function call or variable node using one warns when the Blueprint compiles, C++ warns when it builds, and the four older defense rules show as Deprecated in the editor.

| Deprecated | Use instead |
| --- | --- |
| `USECAbilityTask_ApproachGlideToActor` | `USECAbilityTask_ApproachGlide::ApproachGlide`, passing the target as `Followed` |
| `USECAbilityTask_ApproachGlideToPoint` | `USECAbilityTask_ApproachGlide::ApproachGlide` with no `Followed` actor |
| `USECApproachComponent::IsGliding()` / `GetGlideVelocity()` | `bGliding` / `GlideVelocity` |
| `SECApproachMath::StepYawToward`, the overload taking a deadzone | The overload without a deadzone |
| `SECApproachMath::LeadTarget` | `SECApproachMath::LeadTargetFrom` |
| `SECApproachMath::FWindowClock`, `EWindowPhase` | Nothing: an approach window follows its montage's playback itself |
| `SECMontageWindow::IsSupersededRun` | `SECMontageWindow::HasLeft` |
| `Montage`, `WindowStart`, `WindowEnd`, `EffectiveRate` on `FSECApproachRequest` | An approach window on the montage, or `WindowDuration` |
| `MinLead` on `USECRootMotionModifier_SkewWarp` | Leave it at 1 cm, which ends on the standoff |
| `AEnemyControllerBase::bWarnedPawnFacingUndriven` | Nothing: the pawn facing warning is written once per pawn class and play session |
| `USECVitalsComponent::DeriveVitalEdges`, the float form | The form taking the previous and next anchors |
| `USECDamageStatics::RunHitEffectList`, the seven-argument form | The form taking `bAttackerPlaysAhead` |
| `GetBaseMaxWalkSpeed`, `SetBaseMaxWalkSpeed`, `BaseMaxWalkSpeed` on `USECSpeedModifierComponent` | `GetBaseValue` and `SetBaseValue` with `MaxWalkSpeed` on the character's `USECMovementModifierComponent`; inside an `ApplySpeedScale` override, the parent call or `ScaleValue` |
| `DamageType` on `USECDamageConfig` and on `FSECDamageDefinition` | `DamageTags` |
| `Outcome` on `FSECDefenseResult`, and `ESECDefenseOutcome` | `ResultTags`. The four older rules and Invulnerable still write `Outcome`; Guard and Scale Damage leave it Unguarded |
| `USECDefenseRule::GetDisplayName` | The rule's class display name |
| `USECDefenseRule_Parry`, `_Block`, `_DamageModifier`, `_DamageTypeResistance` | `USECDefenseRule_Guard` and `USECDefenseRule_Scale` (**SEC Guard** and **SEC Scale Damage**) |
| `UAICombatRoleSubsystem::SetCombatTarget` | `RegisterCombatTarget` with `bAutoAssignUnassigned` true |
| `UAICombatRoleSubsystem::GetCombatTarget` | `GetCombatantTarget(Controller)` or `GetAllCombatTargets()` |
| `PreferredNextActionId`, `ChainBonusMultiplier` on `FActionSpec` | `ChainLinks`, with the bonus on the source action's link. Saved values convert into a chain link on load |
| `bManualOnly`, `bChainOnly` on `FActionSpec` | `Selection`, set to Manual Only or Chain Only. Each flag folds into `Selection` on load and on grant |
| `StrafePenaltyThreshold` on `UMovementEvaluatorComponent` | `StrafeFullPenaltyAngle`, the same limit in degrees |

**Replicate** on **Set Approach Target**, **Set Approach Target to Actor** and **Set Approach Target to Location** is deprecated too, and gives no warning, since the engine cannot mark one input of a node deprecated; the node's tooltip says so. It still has the server send the target to the player's own machine.

Previous page: [Performance](https://rigbak.com/docs/soulslike-combat/performance)
