diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs
index b8dc7a2661..236bf9ff00 100644
--- a/osu.Game/Rulesets/Mods/Mod.cs
+++ b/osu.Game/Rulesets/Mods/Mod.cs
@@ -131,22 +131,31 @@ namespace osu.Game.Rulesets.Mods
///
public virtual Mod CreateCopy()
{
- var copy = (Mod)Activator.CreateInstance(GetType());
+ var result = (Mod)Activator.CreateInstance(GetType(), true);
+ result.CopyFrom(this);
+ return result;
+ }
+
+ ///
+ /// Copies properties of given mod into here, through changing value.
+ ///
+ /// The mod to copy properties from.
+ public void CopyFrom(Mod them)
+ {
+ if (them.GetType() != GetType())
+ throw new ArgumentException($"Expected mod of type {GetType()}, got {them.GetType()}.", nameof(them));
- // Copy bindable values across
foreach (var (_, prop) in this.GetSettingsSourceProperties())
{
- var origBindable = prop.GetValue(this);
- var copyBindable = prop.GetValue(copy);
+ var ourBindable = prop.GetValue(this);
+ var theirBindable = prop.GetValue(them);
// The bindables themselves are readonly, so the value must be transferred through the Bindable.Value property.
- var valueProperty = origBindable.GetType().GetProperty(nameof(Bindable