Concept: The Three Layers

CrimsonSettings separates three concerns so each can change independently. Keeping them apart is what lets a setting persist with no glue, or bind to code, or be contributed by another plugin - all through the same screen.

LayerTypeResponsibility
StructureUCrimsonSettingsDataAssetWhat options exist - sections and entries authored in the Content Browser.
BehaviorUCrimsonSettingRegistryHow they read/write - populate from the asset, bind delegates, or wire C++ data sources.
PresentationUCrimsonSettingScreen / UCrimsonSettingPanelHow they look - the CommonUI screen and per-row widgets.

How a value flows

Populate From Data Asset builds one UCrimsonSettingCollection per section and a value object per entry (a _BP class for scalar/discrete, a UCrimsonSettingAction for buttons). For each it fires K2_BindSetting so you can wire behavior, then registers it. Initialize(LocalPlayer) runs OnInitialize, the K2_Register* category hooks, and readies each setting.

Where a value actually lives
A _BP value can source its value three ways, checked in order: a preview value (during live preview), a storage source (the keyed store, when Persist To Shared Store is ticked), a delegate (OnGetValue/OnGetIndex), or finally its internal field. This is why persistence and binding are independent choices - see Concept: Value Types & Data Sources.