API Reference
Public types. Everything here is in the CrimsonCombatText module unless noted.
UCrimsonCombatTextSubsystem
UTickableWorldSubsystem. Owns the simulation - queue, live instances, aggregation, scopes, motion evaluation - and hands each frame to a renderer. 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() | The active UCrimsonCombatTextFilterSet, or null. What the settings layer and the dev tools enumerate |
OnRegistryLoaded | Fires when the async-loaded registry (and its filter set) is ready. Subscribe rather than polling |
ShouldDisplayEvent(Event, OutTrace) | Runs the chain against one event without spawning anything. OutTrace reports which row decided |
BeginCombatTextScope(Target, ScopeTag) | BlueprintCallable | Open an accumulation window without GAS |
EndCombatTextScope(Target, ScopeTag) | BlueprintCallable | Close it and emit the summary |
GetCombatTextScopeTotal(Target, ScopeTag) | BlueprintPure | Running total of an open scope, or 0 |
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 | The ordered visibility chain. Unset means nothing is ever filtered |
AdvancedRules | TArray<FCrimsonCombatTextStyleRule> | Query escape hatch. Empty by default, never scanned unless populated |
ResolveStyle(Tags) | BlueprintNativeEvent | Returns FCrimsonCombatTextResolvedStyle. Override for custom selection |
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; merge repeat hits into one climbing number. 0 = off |
ScopeTag | While the target holds this tag, accumulate into one running total |
ScopeSummaryStyle | Style key for the summary emitted on scope close |
ValueEmphasisScale | Curve: raw value to extra scale multiplier |
ValueEmphasisColor | Curve: raw value to tint |
FCrimsonCombatTextStyleModifier
| Field | Purpose |
|---|
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 |
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 |
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.
| Member | Kind | Purpose |
|---|
BroadcastCombatText(Event) | BlueprintCallable | Server only. Validates authority, resolves location, multicasts |
OnCombatTextReceived | BlueprintAssignable | Fires on each client; the subsystem binds automatically |
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 |
PrefixText / CustomText | Substituted into {Prefix} and {Custom} |
UCrimsonCombatTextSettings
Project Settings > Crimson > Crimson Combat Text.
| Setting | Purpose |
|---|
RegistryPath | The style registry data asset |
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 |
DefaultAggregationWindow / MergeRewindAlpha | Aggregation defaults and merge re-punch point |
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 fallback and tooltip. A Crimson Tag Labels entry for FilterId wins over DisplayName |
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: Tag Labels, then DisplayName, then the raw tag |
GetFilterDescription() | One-line summary for the dev tools and the MCP toolset |
| 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 |