How-To: Filter Which Pops a Player Sees (Optional)
Goal: decide which numbers reach the screen - your own output, an ally's, an enemy's, healing, distant hits - and let the player change that choice. Visibility is authored as an ordered chain of rules in a data asset, not a fixed list of toggles, so you can delete, reorder, retune or add rules without touching code.
FilterSet unset and nothing is ever filtered - this page is entirely optional.1. Create the filter set
Content Browser right-click > Crimson > Combat Text > Filter Set. Name it DA_CrimsonCombatTextFilters, then point your style registry's Filter Set at it. A new asset seeds itself with the seven built-in rows below; the Add Built-In Filters button repopulates it if you clear it.
2. Read the chain
Rows are evaluated top to bottom. The first row that returns a verdict other than Ignore wins; anything no row describes falls through to the set's DefaultResult (Hide).
ShowIncoming below CritsOnly and a non-critical hit on your character stops showing. Reordering is a behavior change, and that is the point.| # | Row | Default | Effect |
|---|---|---|---|
| 0 | Distance | on, 3000cm | Hides text further than the slider from you. Events aimed at you are exempt |
| 1 | ShowHeals | on | Healing, decided before anything looks at who cast it |
| 2 | ShowIncoming | on | What happens to your character |
| 3 | CritsOnly | off | When on, hides everything that is not a critical hit |
| 4 | ShowOwnEffects | on | Damage and healing you cause |
| 5 | ShowAllyEffects | on | Damage and healing your allies cause |
| 6 | ShowEnemyEffects | off | What enemies do to someone other than you |
ShowHeals and CritsOnly are written against Damage.Heal and Damage.Result.Crit. If your damage taxonomy names those differently, open the two rows and edit their Query - the plugin does not own your tags. An empty query matches nothing, so a mismatched row is inert rather than destructive.3. Understand the two verdicts
A row does not decide show-or-hide. It answers Matches - does this rule describe this event? - and the chain then applies `MatchResult` when the player has the row switched on, or `DisabledResult` when they have it off.
That split is what makes the chain work as a user setting. A disabled ShowHeals row has to hide healing; if switching it off merely skipped the row, a heal you cast would fall through to ShowOwnEffects and appear anyway. Two shapes cover almost everything:
| Intent | MatchResult | DisabledResult |
|---|---|---|
| "Show X" - switching it off actively hides X | Show | Hide |
| A restriction - switching it off lifts it | Hide | Ignore |
4. The three built-in rule classes
All seven default rows are instances of just three classes. Add a row and pick one of these before reaching for code.
| Class | Matches when | Key properties |
|---|---|---|
UCrimsonCombatTextFilter_Relationship | The actor in Role is one of the relationships in RelationshipMask. Both sides are normalized to the avatar pawn first, so a player's own output reads as Self | Role (Instigator / Target), RelationshipMask (Self / Ally / Enemy / Unknown), bRequireViewerIsNotOtherRole |
UCrimsonCombatTextFilter_TagQuery | Query matches the event's context tags | Query - a full FGameplayTagQuery, so ANY / ALL / NOT all work |
UCrimsonCombatTextFilter_Distance | The event is further from you than the row's scalar | bExemptWhenViewerIsTarget, plus the scalar (default 3000cm) |
ShowAllyEffects row, set its RelationshipMask to Ally and Enemy, and delete the original two. One row now covers both, and the settings screen shows one toggle instead of two.5. Where the player's choices live
UCrimsonCombatTextPlayerSettings on the local PlayerController holds FilterEnabledOverrides and FilterScalarOverrides, both keyed by FilterId. A row with no entry uses its own bEnabledByDefault / ScalarDefault. Settings are local-only and never replicate.
6. Why did that number not appear?
Once a project authors its own chain, guessing gets expensive. The dev tools Filters tab lists the loaded chain in evaluation order and its decision trace names the row that decided a given event, whether that row was on or off, and the relationships it saw. Run Crimson.CombatText.DevTools in PIE.
See also
- How-To: Write Your Own Filter - a rule the three built-in classes cannot express.
- How-To: Bind Your Team System - make Self / Ally / Enemy mean something.
- How-To: Expose Pop Options as User Settings - drive the chain from a saved options menu.
- Concept: Event Flow & Replication - where in the pipeline the chain runs.