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.
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.
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.
| Row | Storage key | Type |
|---|---|---|
| A filter's on/off | the FilterId tag verbatim, e.g. CrimsonCombatText.Filter.ShowHeals | Discrete bool |
| A filter's tunable | the FilterId tag plus .Value | Scalar, 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.
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.
| StorageKey | Descriptor type | Drives |
|---|---|---|
CrimsonCombatText.WidgetScale | Scalar, range 0.5 - 2.0 | WidgetScale |
CrimsonCombatText.NumberFormat | Discrete, options in this order: Project Default, Comma Separated, Abbreviated, Raw | NumberFormatOverride (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.
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.