diff --git a/Assets/Scripts/InteractionEngine/CommunicationEvents.cs b/Assets/Scripts/InteractionEngine/CommunicationEvents.cs
index 772176dac6824524e01d82809db02e001a0e9451..b6b836d828f324d9cb75153d5636d1cf0d7ba0d0 100644
--- a/Assets/Scripts/InteractionEngine/CommunicationEvents.cs
+++ b/Assets/Scripts/InteractionEngine/CommunicationEvents.cs
@@ -106,6 +106,7 @@ public class AnimationEventWithUris : UnityEvent<List<string>> { }
 
     public enum Directories
     {
+        misc,
         Stages,
         ValidationSets,
         FactStateMachines,
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Fact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Fact.cs
index 754e17ef9d22c3cb22fabdc05d0cdfba7af7dcbe..fe135fe9efa4c8cc576afd430a77aca57d4f94fa 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/Fact.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/Fact.cs
@@ -99,9 +99,12 @@ public abstract class Fact
     public GameObject Representation;
 
     /// <value>
-    /// [ClassName] for JSON de-/serialization
+    /// [ClassName] for JSON de-/serialization.
+    /// Set in every non-abstract subclass of Fact.
+    /// Also add JsonSubtypes.KnownSubType decorator for deserialization to Fact!
     /// </value>
-    public new string s_type;
+    [JsonProperty]
+    protected static readonly /*new*/ string s_type = "ERROR: set s_type in T:Fact"; // In the subtype! NOT here!
 
     /// <value>
     /// Unique Id. e.g.: MMT URI
@@ -482,7 +485,8 @@ protected override bool EquivalentWrapped(AbstractLineFact f1, AbstractLineFact
 public class PointFact : FactWrappedCRTP<PointFact>
 {
     /// \copydoc Fact.s_type
-    public new string s_type = "PointFact";
+    [JsonProperty]
+    protected static readonly new string s_type = "PointFact";
 
     /// <summary> Position </summary>
     public Vector3 Point;
@@ -615,7 +619,8 @@ protected override bool EquivalentWrapped(PointFact f1, PointFact f2)
 public class LineFact : AbstractLineFactWrappedCRTP<LineFact>
 {
     /// \copydoc Fact.s_type
-    public new string s_type = "LineFact";
+    [JsonProperty]
+    protected static readonly new string s_type = "LineFact";
 
     /// <summary> Distance between <see cref="AbstractLineFact.Pid1"/> and <see cref="AbstractLineFact.Pid2"/></summary>
     public float Distance;
@@ -740,7 +745,8 @@ private void SetDistance()
 public class RayFact : AbstractLineFactWrappedCRTP<RayFact>
 {
     /// \copydoc Fact.s_type
-    public new string s_type = "RayFact";
+    [JsonProperty]
+    protected static readonly new string s_type = "RayFact";
 
     /// <summary> \copydoc Fact.Fact </summary>
     public RayFact() : base() { }
@@ -843,7 +849,8 @@ protected override bool EquivalentWrapped(RayFact f1, RayFact f2)
 public class OnLineFact : FactWrappedCRTP<OnLineFact>
 {
     /// \copydoc Fact.s_type
-    public new string s_type = "OnLineFact";
+    [JsonProperty]
+    protected static readonly new string s_type = "OnLineFact";
 
     public string
         /// <summary> <see cref="PointFact"/>.<see cref="Fact.Id">Id</see> </summary>
@@ -1000,7 +1007,8 @@ protected override bool EquivalentWrapped(OnLineFact f1, OnLineFact f2)
 public class AngleFact : FactWrappedCRTP<AngleFact>
 {
     /// \copydoc Fact.s_type
-    public new string s_type = "AngleFact";
+    [JsonProperty]
+    protected static readonly new string s_type = "AngleFact";
 
     /// @{ <summary>
     /// One <see cref="Fact.Id">Id</see> of three <see cref="PointFact">PointFacts</see> defining Angle [<see cref="Pid1"/>, <see cref="Pid2"/>, <see cref="Pid3"/>].
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/SolutionOrganizer.cs b/Assets/Scripts/InteractionEngine/FactHandling/SolutionOrganizer.cs
index 1aa4f8bf94243fd91884e77590ac41154959cc57..f5f4c2e4eed7f410a0e876c1bd8282323ca649f0 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/SolutionOrganizer.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/SolutionOrganizer.cs
@@ -10,7 +10,7 @@
 /// <summary>
 /// Solution of a <see cref="Stage"/>
 /// </summary>
-public class SolutionOrganizer : FactOrganizer
+public class SolutionOrganizer : FactOrganizer, IJSONsavable<SolutionOrganizer>
 {
     /// @{ <summary> adds to the end of the file name of a </summary>
     private const string
@@ -147,62 +147,30 @@ public List<Fact> getMasterFactsByIndex (int i)
     /// @{ 
     /// TODO? move to interface?
     /// TODO: document
-    public new void store(string name, List<Directories> hierarchie = null, bool use_install_folder = false, bool overwrite = true)
+    bool IJSONsavable<SolutionOrganizer>.store(List<Directories> hierarchie, string name, bool use_install_folder, bool overwrite)
     {
-        hierarchie ??= new List<Directories>();
-        hierarchie.AddRange(hierVal.AsEnumerable());
-
-        string path_o = path;
-        path = CreatePathToFile(out bool exists, name + endingVal, "JSON", hierarchie, use_install_folder);
-        hierarchie.RemoveRange(hierarchie.Count - hierVal.Count, hierVal.Count);
-
-        if (exists && !overwrite)
-        {
-            path = path_o;
-            return;
-        }
-
-        JSONManager.WriteToJsonFile(path, this);
-        path = path_o;
+        return (this as IJSONsavable<SolutionOrganizer>).store(hierarchie, name + endingVal, use_install_folder, overwrite);
     }
 
-    public static bool load(ref SolutionOrganizer set, bool draw, string name, List<Directories> hierarchie = null, bool use_install_folder = false)
+    bool IJSONsavable<SolutionOrganizer>.load(List<Directories> hierarchie, string name, out SolutionOrganizer payload, bool use_install_folder)
     {
-        hierarchie ??= new List<Directories>();
-        hierarchie.AddRange(hierVal.AsEnumerable());
+        payload = null;
 
-        string path = CreatePathToFile(out bool loadable, name + endingVal, "JSON", hierarchie, use_install_folder);
-        
-        hierarchie.RemoveRange(hierarchie.Count - hierVal.Count, hierVal.Count);
-        if (!loadable)
+        if (!(this as IJSONsavable<SolutionOrganizer>).load(hierarchie, name, out SolutionOrganizer JsonTmp, use_install_folder))
             return false;
 
-
-        FactOrganizer save = StageStatic.stage.factState;
-        StageStatic.stage.factState = new SolutionOrganizer(false) as FactOrganizer;
-
-        SolutionOrganizer JsonTmp = JSONManager.ReadFromJsonFile <SolutionOrganizer> (path);
-        ReInitializeFactOrganizer(ref StageStatic.stage.player_record.factState, JsonTmp, draw, out Dictionary<string, string> old_to_new);
-
-        set = (SolutionOrganizer)StageStatic.stage.factState;
-        set.path = path;
-        StageStatic.stage.factState = save;
+        payload = ReInitializeFactOrganizer(JsonTmp, false, out Dictionary<string, string> old_to_new)
+            as SolutionOrganizer;
+        payload.path = path;
 
         foreach (var element in JsonTmp.ValidationSet)
         // Parse and add
         {
             element.MasterIDs = new HashSet<string>(element.MasterIDs.Select(k => old_to_new[k]));
-            set.ValidationSet.Add(element);
+            payload.ValidationSet.Add(element);
         }
 
         return true;
     }
-
-    public new void delete()
-    {
-        base.delete();
-        if (System.IO.File.Exists(path))
-            System.IO.File.Delete(path);
-    }
     /// @}
 }
diff --git a/Assets/Scripts/JSONManager.cs b/Assets/Scripts/JSONManager.cs
index 10818cca52d29db2df95f3e4393009ae61e3e8a8..f4e1c7f0d07bfec38169620d31fe6f19332303b5 100644
--- a/Assets/Scripts/JSONManager.cs
+++ b/Assets/Scripts/JSONManager.cs
@@ -8,6 +8,77 @@
 using System.Collections;
 using UnityEngine;
 using Newtonsoft.Json.Linq;
+using static CommunicationEvents;
+
+// I would go for static virtual methods, but C#9 does not allow me...
+// static methods cannot be overwritten -> virtual
+public interface IJSONsavable<T> where T : IJSONsavable<T>, new()
+{
+    // stand in for non static methods
+    public static readonly IJSONsavable<T> Instance = new T(); 
+
+    public string path { get; set; }
+    protected static List<Directories>
+        hierarchie = new List<Directories> { Directories.misc };
+
+    public bool store(List<Directories> hierarchie, string name, bool use_install_folder = false, bool overwrite = true)
+    {
+        return store(hierarchie, name, this, use_install_folder, overwrite);
+    }
+
+    public virtual bool store(List<Directories> hierarchie, string name, IJSONsavable<T> payload, bool use_install_folder = false, bool overwrite = true)
+    {
+        hierarchie ??= new List<Directories>();
+        List<Directories> new_hierarchie = hierarchie.Concat(IJSONsavable<T>.hierarchie) as List<Directories>;
+
+        string path = CreatePathToFile(out bool exists, name, "JSON", new_hierarchie, use_install_folder);
+
+        if (exists && !overwrite)
+            return false;
+
+        JSONManager.WriteToJsonFile(path, payload);
+        return true;
+    }
+
+    public virtual bool load(List<Directories> hierarchie, string name, out T payload, bool use_install_folder = false)
+    {
+        payload = default(T);
+
+        hierarchie ??= new List<Directories>();
+        List<Directories> new_hierarchie = hierarchie.Concat(IJSONsavable<T>.hierarchie) as List<Directories>;
+
+        string path = CreatePathToFile(out bool loadable, name, "JSON", new_hierarchie, use_install_folder);
+        if (!loadable)
+            return false;
+
+        payload = JSONManager.ReadFromJsonFile<T>(path);
+        return true;
+    }
+
+    public virtual bool delete(List<Directories> hierarchie, string name, bool use_install_folder = false)
+    {
+        hierarchie ??= new List<Directories>();
+        List<Directories> new_hierarchie = hierarchie.Concat(IJSONsavable<T>.hierarchie) as List<Directories>;
+
+        string path = CreatePathToFile(out bool _, name, "JSON", new_hierarchie, use_install_folder);
+
+        return delete(path);
+    }
+
+    public virtual bool delete(string path)
+    {
+        if (!File.Exists(path))
+            return false;
+
+        File.Delete(path);
+        return true;
+    }
+
+    public virtual bool delete()
+    {
+        return this.delete(path);
+    }
+}
 
 public class MMTURICollection
 {
diff --git a/Assets/Stages/Stages.meta b/Assets/Stages/Stages.meta
new file mode 100644
index 0000000000000000000000000000000000000000..14ecc71220f57f2ef15c83a94003c48c3add0232
--- /dev/null
+++ b/Assets/Stages/Stages.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 94e80c57976c35c4ab7456cc01dd7a40
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/UserSettings/EditorUserSettings.asset b/UserSettings/EditorUserSettings.asset
index 681b79cabf99eb55d1333b469a01b2d9e37257cb..de6169229735d0d4b5d7f48c907119aafe019280 100644
--- a/UserSettings/EditorUserSettings.asset
+++ b/UserSettings/EditorUserSettings.asset
@@ -5,6 +5,12 @@ EditorUserSettings:
   m_ObjectHideFlags: 0
   serializedVersion: 4
   m_ConfigSettings:
+    RecentlyUsedSceneGuid-0:
+      value: 0502505152005e020c0d0e2446275e44144f19287f707e362c7c4b60b2b9353c
+      flags: 0
+    RecentlyUsedSceneGuid-1:
+      value: 57505505560608585a56557116730644404e4d7b7c7b7562787e4f66e4b1313e
+      flags: 0
     RecentlyUsedScenePath-0:
       value: 22424703114646680e0b0227036c721518021d39630928343f162e27e3f22076f7e93ffdfe
       flags: 0
@@ -43,9 +49,13 @@ EditorUserSettings:
   m_VCDebugCmd: 0
   m_VCDebugOut: 0
   m_SemanticMergeMode: 2
+  m_DesiredImportWorkerCount: 4
+  m_StandbyImportWorkerCount: 2
+  m_IdleImportWorkerShutdownDelay: 60000
   m_VCShowFailedCheckout: 1
   m_VCOverwriteFailedCheckoutAssets: 1
   m_VCProjectOverlayIcons: 1
   m_VCHierarchyOverlayIcons: 1
   m_VCOtherOverlayIcons: 1
   m_VCAllowAsyncUpdate: 1
+  m_ArtifactGarbageCollection: 1