What was wrong in the target plugin
ExpressionRandomizer already uses this exact same registration pattern for almost all its settings, and even has a NewStorableBool()/NewStorableFloat() helper that registers a storable, marks it storeType = Full, and adds it to an "always store" list so it survives serialization — this is precisely the reference plugin's technique, just wrapped in a helper.
However, one real, user-facing setting — the "Remove Paid Morphs" filter toggle — was constructed with a plain new JSONStorableBool(...) instead of that helper. It was never RegisterBool'd and never added to the always-store list, right next to sibling settings (_randomChancesForTransitionsJsb, _chanceToTriggerJsf) whose comments explicitly say "Registered + always-stored so they actually persist in scenes/presets." This looks like a simple oversight — the developer fixed the pattern for its siblings but missed this one field. As a result, this toggle silently reset to its default every time a plugin preset (or a scene) was saved and reloaded.
The fix
One-line change in Init():
csharp
// before
_removePaidMorphsJsb = new JSONStorableBool("Remove Paid Morphs", false, (JSONStorableBool.SetBoolCallback)null);
// after
_removePaidMorphsJsb = NewStorableBool("Remove Paid Morphs", false);
This registers it, sets storeType.Full, and adds it to _alwaysStoreBoolParams — exactly the same treatment its neighboring settings already get, and functionally equivalent to the reference plugin's RegisterBool approach. Nothing else changed: the custom preset system (PresetHandler.cs, RestoreFromPresetJSON), the morph-limits/timing/chance JSON blocks, and all other logic are untouched.