How-To: Use the Ready-Made Collections

Goal: get a complete, working options menu - video, audio, mouse and keyboard, gamepad, gameplay - without authoring a single row, then add your own rows on top of it.

Prerequisites
Quick Start steps 1-2 (the plugin enabled and GameUserSettingsClassName registered). You do not need a data asset for this page.

1. Call the builders

UCrimsonSettingRegistry ships five builders. Each one constructs its collection entirely from this plugin's own storage classes (UCrimsonSettingsLocal / UCrimsonSettingsShared) and setting types, registers it, and returns it so you can append to what it made. They are BlueprintCallable under Settings | Registry | Defaults, so a Blueprint registry can call them too.

In your UCrimsonSettingRegistry Blueprint, override the category hook that matches each builder and call it there:

Event K2_RegisterVideoSettings (LocalPlayer) -> Add Default Video Settings (In Local Player = the event's LocalPlayer pin).

Repeat for K2_RegisterAudioSettings -> Add Default Audio Settings, K2_RegisterInputSettings -> Add Default Mouse And Keyboard Settings and Add Default Gamepad Settings (both, from the one hook), and K2_RegisterGameplaySettings -> Add Default Gameplay Settings.

Each node returns a Crimson Setting Collection - keep the return pin if you plan to add rows to that tab in step 2.

BuilderTabWhat is in it
AddDefaultVideoSettingsVideoSub-collections Display and Graphics, plus the Graphics Quality and Advanced Graphics pages. Window Mode, Resolution, Quality Presets, Auto-Set Quality, device-profile suffix, Brightness, Safe Zone, Color Blind Mode and Strength, Allow HDR, HDR Use Calibration, HDR Paper White, Vertical Sync, Frame Rate Limit (plus Menu / Background / On Battery, and the mobile variant), Dynamic Resolution, 3D Resolution, and the Performance Stats sub-page.
AddDefaultAudioSettingsAudioSub-collections Volume and Sound. Overall / Music / Sound FX / Dialogue / Voice Chat volume, Subtitles, Headphone Mode, HDR Audio Mode, Background Audio, Audio Output Device.
AddDefaultMouseAndKeyboardSettingsMouse & KeyboardSub-collection Mouse Sensitivity: sensitivity X and Y, targeting multiplier, invert vertical, invert horizontal. Then a Keybindings sub-collection with the keyboard and mouse half of the rebindable key list.
AddDefaultGamepadSettingsGamepadSub-collections Hardware, Sensitivity and Dead Zones: controller hardware, force feedback, invert vertical, invert horizontal, look sensitivity preset, ADS look sensitivity preset, move-stick and look-stick dead zones. Then a Keybindings sub-collection with the gamepad half.
AddDefaultGameplaySettingsGameplaySub-collection Language, with the Language row.
Why input splits by device, not by kind
A player arrives at the input screen holding one device and wanting to change how that device behaves. A "Controls" tab of behavior plus a "Keybinds" tab of bindings makes them visit two tabs for one device and shows them the other device's rows on both. So the mouse rows live with the keyboard rebind list, and the pad rows live with the pad rebind list - the way Lyra splits its input screens.
Verify
Open your settings screen. Five tabs, in the order you called the builders. Change Resolution, hit Apply, and the window resizes; change Overall Volume and the mix follows.

2. Append your own rows to a tab

Each builder returns its collection, so adding a row to an existing tab is a matter of holding that return value and calling AddSetting on it - no need to rebuild the tab yourself.

Event K2_RegisterGameplaySettings -> Add Default Gameplay Settings (promote the return value to a variable, GameplayTab) -> Create Discrete Setting (UCrimsonSettingBlueprintLibrary; Outer = self, DevName = AutoSprint, DisplayName = "Auto Sprint") -> Add Setting To Collection (Collection = GameplayTab, Setting = the new one).

Then bind its behavior in K2_BindSetting - see How-To: Bind a Setting to Game Code.

A late child needs RegisterSettingInParent
RegisterSetting walks a collection's children once, at the moment the collection is registered. A child added afterwards is still displayed - the panel walks the tree live - but never reaches RegisteredSettings, so its change events never reach the registry and FindSettingByDevName cannot see it. RegisterSettingInParent(Setting, ParentCollection) registers such a late child on its own, which is what makes the order you build the tree in stop mattering. A null parent falls through to RegisterSetting.
Verify
Your row appears at the bottom of the Gameplay tab, and Find Setting By Dev Name with AutoSprint returns it.

3. Treat DevNames as a contract

Every row's DevName is its identity in three places that outlive the session: the keyed store's StorageKey (which defaults to the DevName), a saved profile's TMap<FName, FString>, and a preset's FCrimsonSettingPresetEntry.

Renaming a DevName loses saved values
A renamed setting is a new setting as far as every store is concerned. It falls back to its default, and the value saved under the old name becomes dead weight nobody reads. Nothing in the framework migrates it for you.

The shipped names above are the ones a project's presets and profiles will refer to. Treat them the way you would a database column name.

RegisterSetting asserts on a duplicate DevName within one registry (ensureAlwaysMsgf), so a collision is loud rather than silent. That is also why the two keybind collections give their category sub-collections device-scoped names (<Collection>_<Category>) rather than sharing one - the same category exists under both devices.

See also

  • How-To: Rebindable Keys - the Keybindings sub-collection both input builders fill.
  • How-To: Brightness & Safe Zone Calibration - the two action rows the Video builder adds.
  • How-To: Performance Stats on the HUD - the Performance Stats sub-page the Video builder adds.
  • Concept: The Three Layers - where a builder sits relative to a data asset.