API Reference
Public types. Everything here is in the CrimsonCombatText module unless noted.
UCrimsonCombatTextSubsystem
UTickableWorldSubsystem. Owns the client-side simulation - queue, live instances, merging, motion evaluation - and hands each frame to a renderer. It renders the totals the server stamped on each event and never accumulates on its own. Never created on a dedicated server.
| Member | Kind | Purpose |
|---|
RequestCombatText(Target, Tags, Value, Prefix, Custom, Instigator, bApplyFilters) | Local/singleplayer entry point. Supply Instigator so relationship rules can judge it; clear bApplyFilters for pops that must always appear | Queue combat text locally. Singleplayer, or client-side effects |
HandleIncomingEvent(Event) | UFUNCTION | Entry point from the replication path; applies per-player filters |
GetFilterSet() | UFUNCTION (BlueprintPure) | The active UCrimsonCombatTextFilterSet, or null. What the settings layer and the dev tools enumerate |
OnRegistryLoaded | FSimpleMulticastDelegate (C++ only) | Fires when the async-loaded registry (and its filter set) is ready. Subscribe rather than polling |
ShouldDisplayEvent(Event, OutTrace) | C++ only | Runs the chain against one event without spawning anything. OutTrace reports which row decided |
| Scope functions | - | Not here. Scopes and running totals are server state on UCrimsonCombatTextReplicationComponent |
UCrimsonCombatTextRegistry
UDataAsset. Maps tags to styles.
| Member | Type | Purpose |
|---|
Styles | TMap<FGameplayTag, FCrimsonCombatTextStyle> | Tag to style. Hierarchical; most specific match wins |
DefaultStyle | FCrimsonCombatTextStyle | Used when nothing matches |
Modifiers | TMap<FGameplayTag, FCrimsonCombatTextStyleModifier> | Orthogonal overlays, applied in ApplyOrder |
MotionSet | UCrimsonCombatTextMotionSet* | Shared motion library styles resolve presets against |
PlacementSet | UCrimsonCombatTextPlacementSet* | Shared placement library styles resolve presets against. Optional - unset anchors everything over its target |
FilterSet | TObjectPtr<UCrimsonCombatTextFilterSet> | The ordered visibility chain. Unset means nothing is ever filtered |
AdvancedRules | TArray<FCrimsonCombatTextStyleRule> | Query escape hatch. Empty by default, never scanned unless populated |
TextStyleTables | TArray<TObjectPtr<UDataTable>> | Editor-only. Rich text style tables (RichTextStyleRow) the authoring dropdowns offer row names from, and the only reason row names can be validated. Never read at runtime |
ResolveStyle(Tags) | BlueprintNativeEvent | Returns FCrimsonCombatTextResolvedStyle. Override for custom selection |
ResolveCompanionPop(ModifierKey, OutResolved) | C++ only | Resolves the companion pop a modifier asks for, keyed by that modifier's own tag. Resolved with an empty modifier list, so a companion can never spawn one of its own. Returns false when the key names no modifier, or one that does not want a companion |
IsDataValid(Context) | Editor override | Validates preset tags, summary style keys and rich text row names across Styles, DefaultStyle, AdvancedRules and Modifiers - including a modifier's CompanionPop, which is a whole style and gets the same checks. A ScopeSummaryStyle that names no Styles row, or whose row would inherit back into the same ledger root, is an error |
UCrimsonCombatTextMotionSet
UDataAsset. A shared library of curve-authored motion presets, seeded with built-ins on creation.
| Member | Type | Purpose |
|---|
Presets | TMap<FGameplayTag, FCrimsonCombatTextMotion> | Named motions. Add rows to define your own |
FindPreset(Tag, OutMotion) | BlueprintCallable | Lookup; false when the tag has no row |
FCrimsonCombatTextStyle
| Field | Purpose |
|---|
FormatString | Rich text. Tokens: {Value}, {Prefix}, {Custom}, {ValueStyle}, {PrefixStyle} |
PrefixStyleTag / ValueStyleTag | Rich-text style rows applied to those segments |
AnimationName | UWidgetAnimation the widget may play |
MotionPreset | Tag resolved against the registry's MotionSet |
Motion | Inline motion, used only when MotionPreset is unset |
PlacementPreset | Tag resolved against the registry's PlacementSet. Unset anchors over the target |
PlacementOffset | Extra offset on top of the placement, in layout units. Slate +Y is DOWN |
AggregationWindow | Seconds between consecutive hits before the server's run lapses. Declaring it makes this row a ledger root. 0 = off. Read on the server |
AggregationDisplay | ECrimsonCombatTextAggregationDisplay. How long one running number lives: fade with its own motion and re-pop the total on the next hit, or hold while the scope is open. Read on the client; inherited from the ledger root like the window and the scope |
ScopeTag | While the target holds this tag, the run never lapses. Also makes this row a ledger root. Watched on the server's copy of the target's ASC |
ScopeSummaryStyle | Style key for the payoff sent when the scope closes - reliably, to each attacker's own PlayerController and to nobody else. An attacker with no controller gets none. Must not inherit back into the same root |
bInheritAggregation | Default true. When this row declares neither a window nor a scope, take the nearest ancestor's (that ancestor is the row's ledger root). Clear it to keep this row's hits out of the parent's running total |
ValueEmphasisScale | Curve: raw value to extra scale multiplier |
ValueEmphasisColor | Curve: raw value to tint |
ECrimsonCombatTextAggregationDisplay
UENUM(BlueprintType). The AggregationDisplay of a style: how long one running number stays on screen. It changes nothing about what the server accumulates, and it is inherited from the ledger root like the window and the scope.
| Value | What happens |
|---|
FadeWithMotion | The default. The number fades when its own motion ends, even while the scope is open; the next hit pops a fresh number already showing the running total |
HoldWhileScoped | The number is pinned on screen while the scope is open and retired by the payoff |
An attacker is a PlayerState wherever one can be reached - see UCrimsonCombatTextPlayerSettings::ResolveInstigatorIdentity - so a row survives respawns and pawns that are not net relevant. Concept: Style Resolution, Motion & Rendering covers the ledger and the multiplayer consequences.
FCrimsonCombatTextStyleModifier
| Field | Purpose |
|---|
ExcludeTags | Hits carrying any of these tags skip the modifier even though its tag matched (hierarchical). The shipped Crit excludes Damage.Type.Poison so a poison crit keeps its own look |
ApplyOrder | Application order when several match, lowest first |
ValueStyleTag | Replaces the style's value row (guarded by its toggle) |
Tint | Multiplied into the instance tint (guarded by its toggle) |
FormatWrapper | Wraps the resolved text; {0} is the base result |
ScaleMultiplier | Multiplies the instance's base render scale |
DurationMultiplier | Multiplies the resolved motion's Duration |
MotionPresetOverride | Swaps the motion wholesale |
PlacementPresetOverride | Re-routes the pop to a different placement |
PlacementOffset | Added to the style's placement offset. Additive across modifiers |
bSpawnCompanionPop | Raise a second, separate pop for this modifier instead of (or as well as) changing the number. Leave every other field at its default for a pure companion |
CompanionPop | FCrimsonCombatTextStyle. The companion's own text, motion, placement and aggregation. Resolved with no modifiers applied, and keyed by this modifier's tag, so it merges only with companions of the same kind on the same target |
FCrimsonCombatTextResolvedStyle
What a registry lookup returns: the base style with every matching modifier applied and Motion already resolved. Modifiers contribute at two levels, which is why this is not just a style - text and motion changes fold into Style, while scale and tint are per-instance and accumulate.
| Field | Purpose |
|---|
Style | FCrimsonCombatTextStyle with modifiers applied and Motion fully resolved |
StyleKey | Which Styles key won. Invalid means DefaultStyle or a rule-chosen inline style |
AggregationRoot | FGameplayTag, BlueprintReadOnly. The Styles key whose window and scope this hit accumulates under - this row itself, or the ancestor it inherited from. Unset when no row in the chain declares either |
ScaleMultiplier | Accumulated instance scale from every applied modifier |
Tint | Accumulated instance tint from every applied modifier |
DurationMultiplier | Accumulated duration multiplier, already folded into Style.Motion.Duration |
Placement | The resolved placement. Null is legal and common: anchor over the target |
PlacementKey | Which PlacementId won. Invalid means the default. Part of the merge identity |
PlacementOffset | The style's offset plus every modifier's, in layout units |
CompanionModifierKeys | Keys of every applied modifier asking for a companion pop, in ApplyOrder. The subsystem resolves each through ResolveCompanionPop and emits it after the main pop |
FCrimsonCombatTextMotion
| Field | Purpose |
|---|
Duration | Lifetime in seconds |
RiseDistance / SpreadDistance | Amplitudes in layout units (post-DPI) |
RiseCurve / SpreadCurve | Normalized alpha to 0..1 progress. Empty = linear |
ScaleCurve | Alpha to scale multiplier. Empty = constant 1 |
OpacityCurve | Alpha to opacity. Empty = opaque until 80%, then linear to 0 |
bUseSpreadFan / FanWidth / FanSlots | Deterministic anti-overlap fan |
RandomJitter | Wobble as a fraction of SpreadDistance. 0 = fully deterministic |
RiseStaggerPerSlot | Extra rise per concurrent hit as a fraction of RiseDistance (-1..1). Ladders the end heights of a burst; 0 = flat stack |
RiseJitter | Random rise variation as a fraction of RiseDistance (0..1), rolled once per instance |
DurationJitter | Random variation in Duration as a fraction of it (0..0.9), rolled once per instance and baked into the instance's duration at spawn |
MergeHoldAlpha | Category Motion|Merge. The lifetime alpha the base motion is held at when a hit merges into this pop (0..1, default 0.6). It parks there instead of rewinding to the anchor |
MergePunchDuration | Seconds the merge punch runs for, on top of the held motion. 0 disables the punch and leaves a plain hold |
MergePunchScaleCurve | Punch progress 0..1 to a scale multiplier on the held sample. Empty = a sine hump 1 -> 1.3 -> 1 |
MergePunchRiseCurve | Punch progress to extra upward layout units, added to the held sample's offset. Empty = 0 |
GetEffectiveDuration(Seed) | Duration after DurationJitter for one seed; the subsystem bakes it at spawn and the preview calls it per slot |
Evaluate(Alpha, Seed) | Returns FCrimsonCombatTextMotionSample (offset, scale, opacity) for a 0..1 lifetime alpha |
ComputeFanFactor(Seed) / ComputeRiseFactor(Seed) | The lateral deflection in -1..1, and the multiplier on RiseDistance, for one seed |
EvaluateMergePunch(PunchAlpha) | Returns the punch's own FCrimsonCombatTextMotionSample for a 0..1 punch alpha - Scale is a multiplier, Offset.Y is additive (negative is up), and Opacity is always 1 and ignored by the composer. Pure; the punch alpha is independent of the lifetime alpha |
DefaultMergePunchScale(PunchAlpha) | Static. The built-in sine hump used when MergePunchScaleCurve is empty |
FCrimsonCombatTextMotionSeed
The per-instance inputs Evaluate needs beyond the alpha. A plain struct, not a USTRUCT - C++ only.
| Field | Purpose |
|---|
SpreadIndex | Fan slot among concurrent hits on the same group. 0 = straight up, and the rung of the end-height ladder |
JitterSeed | Lateral wobble in -1..1, sampled once at spawn |
RiseSeed | Rise wobble in -1..1, sampled once at spawn |
UCrimsonCombatTextRenderer
Abstract presentation strategy, selected by RendererClass. Subclasses key their view state off FCrimsonCombatTextInstance::Handle, never off array position.
| Member | Purpose |
|---|
InitializeRenderer(World, PC) | Returns false if it cannot run; the subsystem then falls back to the widget renderer |
OnTextStarted / OnTextUpdated / OnTextFinished | Per-instance lifecycle |
RenderTexts(Instances, Frames) | Per-frame, all live instances at once. Parallel arrays |
SupportsRichText() | False on the Niagara path; the subsystem warns once |
PreWarm(Count) / GetPooledViewCount() | Optional pooling hooks |
| Implementation | Notes |
|---|
UCrimsonCombatTextRenderer_Widget | Default. One pooled UUserWidget per instance; full rich text. ZOrder sets the viewport layer, so pops can draw over or under your HUD |
UCrimsonCombatTextRenderer_Niagara | One batched Niagara system. No rich text. Needs authored content. Screen-space pops are deprojected onto a camera plane at ScreenSpacePlaneDistance, which world geometry can occlude |
UCrimsonCombatTextWidget
UUserWidget, Abstract, DisableNativeTick. A passive view - no motion, no timing, no lifetime of its own.
| Member | Kind | Purpose |
|---|
ApplyCombatText(Text, StyleKey, AnimationName) | BlueprintNativeEvent | Called when the widget is assigned to a new instance |
OnCombatTextApplied(...) | BlueprintImplementableEvent | Hook for custom visuals or animations |
TextBorder / TextBlock | BindWidgetOptional | Optional stock widgets. TextBlock receives the rich text |
UCrimsonCombatTextReplicationComponent
Lives on the GameState. The server-side broadcast entry point, and the owner of the aggregation ledger: per target and per ledger root, one running row for each attacker identity.
| Member | Kind | Purpose |
|---|
BroadcastCombatText(Event) | BlueprintCallable | Server only. Validates authority, resolves location, stamps the ledger fields onto the event, and sends it |
BeginCombatTextScope(Target, ScopeTag) | BlueprintCallable, Category CrimsonCombatText|Ledger | Server only. Opens a scope by hand for projects without GAS: rows on that target whose style names this tag are held open from the next hit on. Warns and returns without authority |
EndCombatTextScope(Target, ScopeTag) | BlueprintCallable, Category CrimsonCombatText|Ledger | Server only. Closes the scope: each attacker's payoff goes reliably to that attacker's own PlayerController, and to nobody else. An attacker with no controller gets none. The rows are then dropped |
GetCombatTextScopeTotal(Target, ScopeTag, Instigator) | BlueprintPure, Category CrimsonCombatText|Ledger | Server only. Total of the row on Target whose ScopeTag matches, for that attacker identity - normalized through ResolveInstigatorIdentity, with null reading the shared unknown-attacker row. 0 when there is no such row |
OnCombatTextReceived | BlueprintAssignable | Fires on each client; the subsystem binds automatically. Multicast path only |
Hit events go out on unreliable RPCs - Multicast_CombatTextEvent, or UCrimsonCombatTextClientComponent::Client_CombatTextEvent when ServerCullDistance is set. A scope payoff goes out on Client_CombatTextSummary, which is reliable, addressed to one PlayerController and never distance-tested. All of them are protected and internal: gameplay code calls BroadcastCombatText and the scope functions, never the RPCs.
UCrimsonCombatTextTargetComponent
Optional per-actor anchor override.
| Member | Purpose |
|---|
RelativeOffset / SocketName | Where text appears. A valid socket wins over the offset |
ResolveAnchorLocation(Actor) | One-shot world anchor. Used by the server for the event's fallback location and by UCrimsonCombatTextPlacement_WorldActor for its first frame |
ResolveAnchor(...) / EvaluateAnchor(...) | Re-evaluatable anchor so text can follow a moving or animating target |
UCrimsonCombatTextPlacement
Abstract, Blueprintable, EditInlineNew. Decides where one pop sits. Instances are shared by every pop routed to them, so both entry points are const and all per-pop data lives in the state struct.
| Member | Kind | Purpose |
|---|
PlacementId | FGameplayTag | Key styles route to. Restricted to CrimsonCombatText.Placement |
ScreenOffset | FVector2D | Added to the resolved anchor every frame, in layout units |
Fallback | UCrimsonCombatTextPlacement* (Instanced) | Tried when this placement declines. Chains walk up to 4 deep |
AcquirePlacement(Context, OutState) | BlueprintNativeEvent | Spawn time. Return false to decline the pop |
UpdatePlacement(Context, State) | BlueprintNativeEvent | Per frame while bUpdateEveryFrame. Returns the new state |
GetPlacementDescription() | virtual | Short description shown in the dev tools |
| Built-in | Notes |
|---|
UCrimsonCombatTextPlacement_WorldActor | The default. AnchorActor, SocketOverride, WorldOffset, bFollowTarget, bFallBackToEventLocation, bClampToViewportEdge, ViewportEdgePadding |
UCrimsonCombatTextPlacement_ScreenAnchor | Fixed HUD spot. ViewportAnchor, AnchorOffset |
UCrimsonCombatTextPlacement_Widget | Anchored to registered UI. AnchorId, bUseTargetActorContext, WidgetAlignment, AnchorOffset, bHideWhenAnchorLost |
FCrimsonCombatTextPlacementContext
What a placement is told. Its actor pointers are raw and rewritten each frame - never store a copy.
| Field | Purpose |
|---|
TargetActor / InstigatorActor | Who was hit, and who hit them. Either may be null on a client |
EventWorldLocation / bHasEventWorldLocation | The network fallback location carried by the event |
ContextTags / StyleKey / Value | What the pop was requested with, and which style won |
ViewingPlayer | The player this pop is drawn for |
ViewportSize / ViewportScale | Viewport in layout units, and the DPI scale that produced it |
TimeAlive / Alpha | Age in seconds, and normalized 0..1 lifetime progress. Both 0 during acquire |
FCrimsonCombatTextPlacementState
What a placement returns, and its entire per-pop memory.
| Field | Purpose |
|---|
Space | World or Screen. Screen is exempt from camera-distance culling |
WorldAnchor | World anchor. Meaningless in Screen space |
ScreenPosition | Final anchor in layout units. Filled in both spaces |
ScreenOffset | Constant offset folded into the motion offset each frame |
bOnScreen | false hides the pop this frame |
bUpdateEveryFrame | false freezes this state for the rest of the pop's life |
bFollowAnchor | Keep re-resolving the world anchor. Distinct from bUpdateEveryFrame: a pinned pop still re-projects because the camera moves |
AnchorComponent / AnchorSocket / AnchorOffset | The world-follow cache, so an animated socket costs no component search per frame |
SpreadOwner / SpreadGroup | Anti-overlap fan grouping. Pops sharing both deflect away from each other |
UserVector / UserScalar | Scratch for custom placements. Ignored by the plugin |
UCrimsonCombatTextPlacementSet
Data asset holding the named placements. An Instanced array rather than a map, because instancing is reliable on array elements and unreliable on map values.
| Member | Kind | Purpose |
|---|
Placements | TArray<UCrimsonCombatTextPlacement*> (Instanced) | The rows. Each carries its own PlacementId |
FindPlacement(Tag) | BlueprintCallable | Null when the tag is unset or no row carries it |
SeedBuiltInPlacements() | CallInEditor | Adds any missing built-in rows. Never overwrites an id you authored |
UCrimsonCombatTextPlacementLibrary
The maths a placement needs, exposed to Blueprint so custom placements are not C++-only.
| Function | Purpose |
|---|
ProjectWorldToLayout(Context, World, OutLayout) | World point to layout units. false behind the camera |
ClampToViewportEdge(Context, World, Layout, bProjected, Padding) | Pushes an off-screen position to the padded viewport edge, handling anchors behind the camera |
ViewportAnchorToLayout(Context, NormalizedAnchor, PixelOffset) | Normalized viewport anchor to layout units |
GetActorAnchorLocation(Actor) | The actor's combat text anchor: target component socket, its offset, else 100 cm above the root |
UCrimsonCombatTextAnchorSubsystem
World subsystem making UI widgets addressable by tag. Local and cosmetic - never created on a dedicated server. Holds weak pointers, so a destroyed widget cannot dangle.
| Member | Kind | Purpose |
|---|
RegisterAnchorWidget(Id, Widget, ContextActor) | BlueprintCallable | Null ContextActor registers the global anchor for that id |
UnregisterAnchorWidget(Id, ContextActor) | BlueprintCallable | Drops one registration |
UnregisterAllAnchorsForWidget(Widget) | BlueprintCallable | Drops every id a widget registered |
FindAnchorWidget(Id, ContextActor) | BlueprintPure | Per-actor registration wins over the global one |
GetAnchorViewportPosition(Id, ContextActor, Alignment, OutPos) | BlueprintCallable | Layout-unit position. false when unregistered, hidden, destroyed, or never painted |
UCrimsonCombatTextAnchorWidget
A USizeBox that registers itself as an anchor for its lifetime. Palette category Crimson.
| Member | Kind | Purpose |
|---|
AnchorId | FGameplayTag | The id to register under. Deliberately unrestricted - these name your widgets |
SetAnchorId(Id) | BlueprintCallable | Re-registers under a new id |
SetAnchorContextActor(Actor) | BlueprintCallable | Makes this a per-actor anchor, for nameplates |
FCrimsonCombatTextEvent
| Field | Purpose |
|---|
Value | The number to display |
Tags | Selects style and modifiers; also drives per-player filtering |
WorldLocation / bHasWorldLocation | Server-resolved position, FVector_NetQuantize (1cm) |
Instigator / Target | May be null on clients where the actor is not net-relevant |
InstigatorIdentity | Who the instigator is, for per-attacker totals - the instigator's PlayerState wherever one can be reached. Filled server-side by BroadcastCombatText when you leave it unset, and replicated with the event, because a PlayerState stays relevant when the pawn that swung does not |
PrefixText / CustomText | Substituted into {Prefix} and {Custom} |
LedgerRoot | Stamped by the server: the Styles key whose window and scope this hit accumulates under. Unset means the hit is in no ledger |
InstigatorTotal / InstigatorHitCount | Stamped by the server: this attacker's running total on this target under that root, including this hit, and how many hits are in the run. A count of 1 is a fresh number; 0 means the hit is in no ledger |
bLedgerScopeOpen | A scope is holding the run open - the number stays on screen until the summary arrives |
bLedgerSummary | This event is a scope payoff carrying the final total in Value. It never feeds the ledger, and it retires the held number it pays off |
UCrimsonCombatTextSettings
Project Settings > Crimson > Crimson Combat Text.
| Setting | Purpose |
|---|
RegistryPath | The style registry data asset. Required on a dedicated server too - the replication component loads it itself to resolve ledger roots |
WidgetClassPath | Widget Blueprint for the widget renderer |
RendererClass | Presentation strategy. Unset falls back to the widget renderer |
NumberFormat | CommaSeparated / Abbreviated / Raw |
DistanceScaleCurvePath | Optional camera-distance to scale multiplier |
ServerCullDistance | 0 = multicast to all; > 0 = per-client RPCs within range |
InitialPoolSize / MaxActiveTexts | Pool pre-warm and concurrent cap (0 = unlimited) |
SpreadDecayTime | How long a burst keeps fanning before resetting to center |
bVerboseLogging | Per-dispatch logging. Off in shipping |
UCrimsonCombatTextFilter
Abstract, Blueprintable, EditInlineNew. One rule in the visibility chain. Instances are shared by every pop that runs through the set and must stay stateless, which is why Matches is const.
| Member | Purpose |
|---|
Matches(Context) | BlueprintNativeEvent. Does this rule describe this event? - not a verdict. Override this |
FilterId | Identity, under CrimsonCombatText.Filter. Also the settings storage key and the player-override key |
DisplayName / Description | Label and tooltip. The tag-label resolver, when bound, can rename the label |
bUserConfigurable | False hides the row from the settings screen and pins it to bEnabledByDefault |
bEnabledByDefault | The state the row starts in |
MatchResult | Verdict when the row is ON and Matches returns true |
DisabledResult | Verdict when the row is OFF and Matches returns true |
bHasScalarParameter | Row exposes one tunable. Read it in Matches from Context.ScalarParameter, never from ScalarDefault |
ScalarDisplayName / ScalarRange / ScalarStep / ScalarDefault | Slider label, bounds, step and starting value |
GetFilterDisplayName() / GetScalarDisplayName() | Resolved labels: the tag-label resolver when bound, else DisplayName, else the raw tag |
GetFilterDescription() | One-line summary for the dev tools |
| Built-in | Matches when |
|---|
UCrimsonCombatTextFilter_Relationship | The actor in Role (Instigator / Target) is in RelationshipMask. bRequireViewerIsNotOtherRole excludes self-inflicted events |
UCrimsonCombatTextFilter_TagQuery | Query matches the event's context tags. An empty query matches nothing |
UCrimsonCombatTextFilter_Distance | Further from the viewer than the scalar. bExemptWhenViewerIsTarget spares events aimed at you |
UCrimsonCombatTextFilterSet
UDataAsset. The ordered chain, assigned on the registry. An Instanced array with an id on each row rather than a TMap - a map has no order, and UPROPERTY(Instanced) is unreliable on map values.
| Member | Purpose |
|---|
Filters | The chain, evaluated top to bottom. First non-Ignore verdict wins |
DefaultResult | Verdict when no row had an opinion. Hide by default |
FindFilter(FilterId) | Row lookup by tag, through a rebuilt index |
GetUserConfigurableFilters() | The rows a settings screen should offer, in chain order |
SeedDefaultFilters() | CallInEditor. Adds the seven built-in rows; never overwrites an id you already authored |
FCrimsonCombatTextFilterContext
What a filter is told. Built once per event, before the chain runs, and handed to every row unchanged - so relationship is resolved once no matter how long the chain is.
| Field | Meaning |
|---|
InstigatorActor / TargetActor | Weak pointers, normalized to the avatar pawn. Frequently null on clients |
InstigatorRelationship / TargetRelationship | Self / Ally / Enemy / Unknown. A null side goes to the team hook and reads as Ally; Unknown means there was no viewing pawn |
bViewerIsInstigator / bViewerIsTarget | Direct identity against the viewing pawn |
ContextTags / Value | The pop as requested, before style resolution |
EventWorldLocation / bHasEventWorldLocation | Server-resolved anchor; survives a null target |
ViewingPawn / ViewingPlayer | Who the text is being drawn for |
ScalarParameter | The tunable for the row being evaluated - the player's override, or its ScalarDefault |
UCrimsonCombatTextPlayerSettings
PlayerController component. Per-player filter choices, display overrides and placement re-routing. Local only, never replicated, and the plugin does not persist it.
| Member | Purpose |
|---|
FilterEnabledOverrides | FilterId -> on/off. No entry means the row's bEnabledByDefault |
FilterScalarOverrides | FilterId -> tunable. No entry means the row's ScalarDefault |
SetFilterEnabled(FilterId, bEnabled) / ClearFilterEnabledOverride(FilterId) | Set or clear the player's choice for one row |
IsFilterEnabled(Filter) / GetFilterScalar(Filter) | The values actually in effect. A non-configurable row always reports its authored default |
ResolveEventActor(Actor) | Static. Normalizes an event actor to its avatar pawn - a GAS instigator is the ASC owner (the PlayerState), the target is the pawn. Without this a player's own damage never reads as Self |
BuildFilterContext(Event, LocalPawn) | Builds the context the chain runs against, resolving both relationships up front |
PassesFilter(Event, LocalPawn, FilterSet, OutTrace) | Walks the chain. A null FilterSet passes everything |
IsActorFriendly(LocalPawn, Other) | BlueprintNativeEvent team hook. Asked at most twice per event |
IsActorFriendlyDelegate | C++ binding for the same hook. Unbound treats every actor as an ally |
WidgetScale / NumberFormatOverride | Per-player render scale and number format (-1 = project default) |
PlacementOverrides | Style key -> placement id, matched hierarchically. Most specific entry wins |
ApplyPlacementOverride(Resolved, PlacementSet) | Applied after style resolution, before the placement is acquired. A stale id warns and keeps the authored placement |