How-To: Expose Pop Options as User Settings (Optional)

Goal: surface the per-player pop options in a saved options menu. The visibility half is generated from the filter chain, not hand-authored - add a row to the filter set and it becomes a settings row, with no descriptor to write and no key to invent.

Prerequisites
CrimsonCore + CrimsonSettings in the project, with your PlayerController derived from ACrimsonPlayerController. Standalone (without CrimsonCore), skip this page: call SetFilterEnabled / SetFilterScalar on UCrimsonCombatTextPlayerSettings from your own options UI and persist the two maps yourself.

1. Generate the filter rows

Call this from your UCrimsonSettingRegistry subclass - C++ OnInitialize, or the Blueprint K2_RegisterGameplaySettings event. It walks the loaded filter set and adds one toggle per user-configurable row, in chain order, plus a slider for any row with a scalar.

In your settings registry Blueprint, override Register Gameplay Settings, make a collection, and pass it to Register Combat Text Filter Settings.

K2_RegisterGameplaySettings -> Create Collection -> Register Combat Text Filter Settings -> K2 Register Setting.
Verify
Open your options screen. Seven combat text toggles appear in chain order, with a Max Display Distance slider under the first. Turn one off, restart, and it is still off.
The registry is async-loaded
The combat text filter set usually does not exist yet the first time a settings registry initializes on a fresh level, and the generator returns nothing. Subscribe to UCrimsonCombatTextSubsystem::OnRegistryLoaded and call Regenerate() on your registry if your settings screen can be built that early.

2. Where the keys come from

Every row's storage key is derived from its `FilterId` rather than hand-written. That is what makes a filter a project wrote itself persist with no glue to update - and it means there is no list of key names to keep in sync.

RowStorage keyType
A filter's on/offthe FilterId tag verbatim, e.g. CrimsonCombatText.Filter.ShowHealsDiscrete bool
A filter's tunablethe FilterId tag plus .ValueScalar, using the row's ScalarRange / ScalarStep

Labels come from Project Settings > Crimson > Tag Labels, keyed by FilterId, falling back to the filter's own DisplayName - so renaming a setting never means opening the asset.

Untouched keys keep authored defaults
Each row's bEnabledByDefault / ScalarDefault doubles as the store's default, so a player who never opens the menu keeps whatever the designer chose.

3. The two display options are still hand-authored

Scale and number format are not filters, so they keep fixed key names. Add one descriptor each to a UCrimsonSettingsDataAsset (see the CrimsonSettings wiki -> How-To: Expose Another Plugin's Settings), with bPersistToSharedStore = true and StorageKey set to the exact name below.

UCrimsonSettingsDataAsset -> a combat text entry with bPersistToSharedStore ticked and StorageKey = CrimsonCombatText.WidgetScale.
StorageKeyDescriptor typeDrives
CrimsonCombatText.WidgetScaleScalar, range 0.5 - 2.0WidgetScale
CrimsonCombatText.NumberFormatDiscrete, options in this order: Project Default, Comma Separated, Abbreviated, RawNumberFormatOverride (option index - 1 maps to -1..2)

The NumberFormat discrete stores an option index and the glue maps index - 1 onto NumberFormatOverride, so the options must be authored in exactly that order: Project Default (0 -> -1), Comma Separated (1 -> 0), Abbreviated (2 -> 1), Raw (3 -> 2).

4. How values reach the game

UCrimsonCoreCombatTextSettingsComponent is a default component on ACrimsonPlayerController. It reads the same keys back and pushes them onto the local player's UCrimsonCombatTextPlayerSettings, creating that component on demand - so you never add it yourself. It is event-driven and re-applies whenever a shared setting changes, which is why sliders update live.

The team bridge is separate
This page covers the options. The Self / Ally / Enemy relationship itself comes from the IsActorFriendly team hook - see How-To: Bind Your Team System.

See also

  • CrimsonSettings wiki -> How-To: Expose Another Plugin's Settings - authoring descriptors, widgets, and screens.
  • How-To: Filter Which Pops a Player Sees - the chain these rows control.
  • How-To: Write Your Own Filter - add a row and it appears here automatically.