How-To: Expose Another Plugin's Settings

Goal: surface options that belong to a different plugin (camera, input, a gameplay system) in a settings screen - without CrimsonSettings depending on that plugin, and without adding fields to CrimsonSettings. The keyed store makes this a data-authoring task, not a code-coupling one.

The rule this respects
CrimsonSettings stores only opaque Key -> value pairs; it never names a camera or gameplay concept. The consuming module (which already sees both plugins) reads those keys and applies them. So neither plugin gains a dependency on the other.

1. Author the options with storage keys

Add the options to a settings data asset section, tick Persist To Shared Store, and give each a stable, namespaced Storage Key. Namespace the key after the system that will read it, so two systems authored by different people cannot collide. A gameplay module might publish these:

OptionTypeStorage Key
Aim sensitivityScalarGameplay.AimSensitivity
Aim assist strengthScalarGameplay.AimAssistStrength
Hold to sprintDiscreteGameplay.HoldToSprint
Screen-shake intensityScalarGameplay.ScreenShakeScale
Verify
The options appear in your screen and persist. Nothing is wired yet - the next step makes them take effect.

2. Apply the values in a module that sees both plugins

A consumer reads the keys and pushes them onto the target system. Read the value once when the consumer starts, and again whenever the store reports a change:

cpp
// In YOUR module (which depends on CrimsonSettings AND the target plugin):
if (UCrimsonSharedSettingsSubsystem* Sub = UCrimsonSharedSettingsSubsystem::Get(LocalPlayer))
{
if (UCrimsonSettingsShared* S = Sub->GetSharedSettings())
{
AimComponent->SetSensitivity(S->GetFloatValue(FName("Gameplay.AimSensitivity"), 1.f));
MovementComponent->SetHoldToSprint(S->GetBoolValue(FName("Gameplay.HoldToSprint"), true));
}
}
// Re-apply on UCrimsonSettingsShared::OnSettingChanged so live edits take effect.
Where the apply layer lives
The consumer must depend on both CrimsonSettings and the target plugin - so it belongs in your game module, never inside CrimsonSettings or the target plugin. That single module is the only place the two names meet.
React to changes
UCrimsonSettingsShared broadcasts OnSettingChanged whenever any keyed value changes, and UCrimsonSharedSettingsSubsystem auto-saves on a short debounce. Subscribe to that event to re-apply live while the player drags a slider.

See also

  • Concept: Storage Model - the keyed store and the shared-settings subsystem.
  • How-To: Persist Settings with Zero Glue - the authoring half of this pattern.