diff --git a/Assets/Scripts/GenerateDemoFiles.cs b/Assets/Scripts/GenerateDemoFiles.cs
index 09e7b0958acb842855f5546fbe62327246fda9b2..f30520b4d57f3306f0ff738de1164569a2b27c7e 100644
--- a/Assets/Scripts/GenerateDemoFiles.cs
+++ b/Assets/Scripts/GenerateDemoFiles.cs
@@ -25,13 +25,13 @@ public static void GenerateDemoA()
         // TODO? use constructor
         Stage demo = new Stage
         {
-            number = 0,
+            number = 1,
             category = "Demo Category",
             name = "TechDemo A",
             scene = "RiverWorld",
             description = "Tree Stage",
             use_install_folder = true,
-            hierarchie = new List<Directories> { /*Directories.Stages*/ }
+            //hierarchie = new List<Directories> { /*Directories.Stages*/ }
         };
 
         // needed to generate facts
@@ -58,6 +58,7 @@ public static void GenerateDemoA()
             { new SolutionOrganizer.SubSolution(new HashSet<string> { target_Id }, null, null, new LineFactHightDirectionComparer()) };
 
         // Save
+        StageStatic.SetMode(StageStatic.Mode.Create);
         StageStatic.stage.store();
     }
 
@@ -70,13 +71,13 @@ public static void GenerateDemoB()
         // TODO? use constructor
         Stage demo = new Stage
         {
-            number = 0,
+            number = 2,
             category = "Demo Category",
             name = "TechDemo B",
             scene = "RiverWorld",
             description = "River Stage",
             use_install_folder = true,
-            hierarchie = new List<Directories> { /*Directories.Stages*/ }
+            //hierarchie = new List<Directories> { /*Directories.Stages*/ }
         };
 
         // needed to generate facts
@@ -106,6 +107,7 @@ public static void GenerateDemoB()
             };
 
         // Save
+        StageStatic.SetMode(StageStatic.Mode.Create);
         StageStatic.stage.store();
     }
 }
diff --git a/Assets/Scripts/GlobalBehaviour.cs b/Assets/Scripts/GlobalBehaviour.cs
index a356eaa98c1ad2a2e41098f2faf7e90d1c539940..f51ac1698f99234db8fe9e277136fcd512c853d0 100644
--- a/Assets/Scripts/GlobalBehaviour.cs
+++ b/Assets/Scripts/GlobalBehaviour.cs
@@ -36,7 +36,7 @@ public class GlobalBehaviour : MonoBehaviour
 
     void Awake()
     {
-        // GenerateDemoFiles.GenerateAll();
+         GenerateDemoFiles.GenerateAll();
 
         hintAnimationStartColor = _hintAnimationStartColor;
         hintAnimationEndColor = _hintAnimationEndColor;
diff --git a/Assets/Scripts/InteractionEngine/CommunicationEvents.cs b/Assets/Scripts/InteractionEngine/CommunicationEvents.cs
index b6b836d828f324d9cb75153d5636d1cf0d7ba0d0..0006129c45f449f7272e4a673299c964f3647313 100644
--- a/Assets/Scripts/InteractionEngine/CommunicationEvents.cs
+++ b/Assets/Scripts/InteractionEngine/CommunicationEvents.cs
@@ -108,6 +108,7 @@ public enum Directories
     {
         misc,
         Stages,
+        SaveGames,
         ValidationSets,
         FactStateMachines,
     }
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Fact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Fact.cs
index fe135fe9efa4c8cc576afd430a77aca57d4f94fa..bf35f56333cb709d5f585ca674d5d07c3d12ba25 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/Fact.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/Fact.cs
@@ -104,7 +104,7 @@ public abstract class Fact
     /// Also add JsonSubtypes.KnownSubType decorator for deserialization to Fact!
     /// </value>
     [JsonProperty]
-    protected static readonly /*new*/ string s_type = "ERROR: set s_type in T:Fact"; // In the subtype! NOT here!
+    protected static /*new*/ string s_type = "ERROR: set s_type in T:Fact"; // In the subtype! NOT here!
 
     /// <value>
     /// Unique Id. e.g.: MMT URI
@@ -125,9 +125,10 @@ public string Id {
     /// </value>
     public string Label {
         get { // in case of renamed dependables
-            return hasCustomLabel && _CustomLabel != null ?
-                _CustomLabel :
-                generateLabel();
+            return _Facts.FactDict.Count == 0 
+                || (hasCustomLabel && _CustomLabel != null) 
+                ? _CustomLabel
+                : generateLabel();
         }
         set { rename(value); }
     }
@@ -486,7 +487,7 @@ public class PointFact : FactWrappedCRTP<PointFact>
 {
     /// \copydoc Fact.s_type
     [JsonProperty]
-    protected static readonly new string s_type = "PointFact";
+    protected static new string s_type = "PointFact";
 
     /// <summary> Position </summary>
     public Vector3 Point;
@@ -620,7 +621,7 @@ public class LineFact : AbstractLineFactWrappedCRTP<LineFact>
 {
     /// \copydoc Fact.s_type
     [JsonProperty]
-    protected static readonly new string s_type = "LineFact";
+    protected static new string s_type = "LineFact";
 
     /// <summary> Distance between <see cref="AbstractLineFact.Pid1"/> and <see cref="AbstractLineFact.Pid2"/></summary>
     public float Distance;
@@ -746,7 +747,7 @@ public class RayFact : AbstractLineFactWrappedCRTP<RayFact>
 {
     /// \copydoc Fact.s_type
     [JsonProperty]
-    protected static readonly new string s_type = "RayFact";
+    protected static new string s_type = "RayFact";
 
     /// <summary> \copydoc Fact.Fact </summary>
     public RayFact() : base() { }
@@ -850,7 +851,7 @@ public class OnLineFact : FactWrappedCRTP<OnLineFact>
 {
     /// \copydoc Fact.s_type
     [JsonProperty]
-    protected static readonly new string s_type = "OnLineFact";
+    protected static new string s_type = "OnLineFact";
 
     public string
         /// <summary> <see cref="PointFact"/>.<see cref="Fact.Id">Id</see> </summary>
@@ -1008,7 +1009,7 @@ public class AngleFact : FactWrappedCRTP<AngleFact>
 {
     /// \copydoc Fact.s_type
     [JsonProperty]
-    protected static readonly new string s_type = "AngleFact";
+    protected static 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/FactOrganizer.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactOrganizer.cs
index b480dd2047bc14dac0b707eba26bfd3eff459125..4dcc1769bbf7ad7e6983aaeb417f0da87a878a8f 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/FactOrganizer.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/FactOrganizer.cs
@@ -91,6 +91,7 @@ public class FactOrganizer : IJSONsavable<FactOrganizer>
     /// @{ <summary>
     /// For <see cref="store(string, List<Directories>, bool, bool)"/> and <see cref="load(ref FactOrganizer, bool, string, List<Directories>, bool, out Dictionary<string, string>)"/>
     /// </summary>
+    public string name { get; set; } = null;
     public string path { get; set; } = null;
     /// @}
 
@@ -215,7 +216,7 @@ public FactOrganizer(bool invoke = false)
     /// <param name="source">instance to be parsed</param>
     /// <param name="invoke">see <see cref="invoke"/></param>
     /// <param name="old_to_new">generated to map <c>Key</c> <see cref="Fact.Id"/> of <paramref name="source"/> to corresponding <c>Value</c> <see cref="Fact.Id"/> of <paramref name="target"/></param>.
-    protected static T ReInitializeFactOrganizer<T>
+    public static T ReInitializeFactOrganizer<T>
         (FactOrganizer source, bool invoke, out Dictionary<string, string> old_to_new)
          where T : FactOrganizer, new()
     {
diff --git a/Assets/Scripts/JSONManager.cs b/Assets/Scripts/JSONManager.cs
index f25499f2e112065eb38b257fef277a64c0670f01..afb7adfd623d55f05fbb5bd4a2c4fcde32932c7d 100644
--- a/Assets/Scripts/JSONManager.cs
+++ b/Assets/Scripts/JSONManager.cs
@@ -14,35 +14,50 @@
 // 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(); 
+    // stand-in for non static methods
+    public static readonly IJSONsavable<T> Instance = new T();
+    public static readonly FieldInfo[] JsonSeperateFields =
+         typeof(T)
+        .GetFields(
+            BindingFlags.Instance |
+            BindingFlags.Public |
+            BindingFlags.NonPublic |
+            BindingFlags.Static )
+        .Where((field)
+            => field.GetCustomAttributes().Any((attribute) 
+                => attribute.GetType() == typeof(JSONManager.JsonSeparateAttribute))
+            && field.FieldType.GetInterfaces().Any((inter) 
+                => inter.IsGenericType && inter.GetGenericTypeDefinition() == typeof(IJSONsavable<>)))
+        .ToArray();
+
 
+    // TODO: this?
+    public string name { get; set; }
     public string path { get; set; }
     protected static List<Directories>
         hierarchie = new List<Directories> { Directories.misc };
 
     #region OverridableMethods
 
-    protected virtual string _IJGetName(string name) => name;
-    protected virtual List<Directories> _IJGetHierarchie(List<Directories> hierarchie_base)
+    public virtual string _IJGetName(string name) => name;
+    public virtual List<Directories> _IJGetHierarchie(List<Directories> hierarchie_base)
     {
         hierarchie_base ??= new List<Directories>();
         return hierarchie_base.Concat(hierarchie).ToList();
     }
-    protected virtual T _IJGetRawObject(string path) => JSONManager.ReadFromJsonFile<T>(path);
-    protected virtual T _IJPreProcess(T payload) => payload;
-    protected virtual T _IJPostProcess(T payload) => payload;
+    public virtual bool _IJGetRawObject(out T payload, string path) => JSONManager.ReadFromJsonFile<T>(out payload, path);
+    public virtual T _IJPreProcess(T payload) => payload;
+    public virtual T _IJPostProcess(T payload) => payload;
 
     #endregion OverridableMethods
 
+
     #region MethodTemplates
 
-    public bool store(List<Directories> hierarchie, string name, bool use_install_folder = false, bool overwrite = true)
-    {
-        return store(hierarchie, name, (T) this, use_install_folder, overwrite);
-    }
+    public bool store(List<Directories> hierarchie, string name, bool use_install_folder = false, bool overwrite = true, bool deep_store = true)
+        => store(hierarchie, name, (T) this, use_install_folder, overwrite, deep_store);
 
-    public static bool store(List<Directories> hierarchie, string name, T payload, bool use_install_folder = false, bool overwrite = true)
+    public static bool store(List<Directories> hierarchie, string name, T payload, bool use_install_folder = false, bool overwrite = true, bool deep_store = true)
     {
         var new_hierarchie = 
             Instance._IJGetHierarchie(hierarchie);
@@ -53,6 +68,12 @@ public static bool store(List<Directories> hierarchie, string name, T payload, b
         if (exists && !overwrite)
             return false;
 
+        // store fields decorated with JsonSeparateAttribute and implementing IJSONsavable<> separately
+        if (deep_store
+            && !store_children(hierarchie, name, payload, use_install_folder: false, overwrite, deep_store: true))
+                return false;
+
+        // store this
         string path_o = payload.path;
         payload.path = path;
 
@@ -64,23 +85,114 @@ public static bool store(List<Directories> hierarchie, string name, T payload, b
         JSONManager.WriteToJsonFile(path, new_payload);
         return true;
     }
+    
+    public bool store_children(List<Directories> hierarchie, string name, bool use_install_folder = false, bool overwrite = true, bool deep_store = true)
+        => store_children(hierarchie, name, (T) this, use_install_folder, overwrite, deep_store);
+
+    public static bool store_children(List<Directories> hierarchie, string name, T payload, bool use_install_folder = false, bool overwrite = true, bool deep_store = true)
+    {
+        var new_hierarchie =
+            Instance._IJGetHierarchie(hierarchie);
+        var new_name =
+            Instance._IJGetName(name);
+
+        for ((int max_i, bool success) = (0, true); max_i < JsonSeperateFields.Count(); max_i++)
+        {
+            var field = JsonSeperateFields[max_i];
+            dynamic save_me = field.GetValue(payload); // is S:IJSONsavable<S>
+
+            Type interface_type = typeof(IJSONsavable<>).MakeGenericType(field.FieldType);
+            Type[] store_args_type = new Type[] { typeof(List<Directories>), typeof(string), field.FieldType, typeof(bool), typeof(bool), typeof(bool) };
+            object[] store_args = new object[] { new_hierarchie, new_name, save_me, use_install_folder, overwrite, deep_store };
+
+            var method = interface_type.GetMethod("store", store_args_type);
+            success &= (bool)method.Invoke(null, store_args);
+
+            // in case of no success: delete it again
+            if (!success)
+            {
+                delete_children(hierarchie, name, use_install_folder, JsonSeperateFields.Count() - max_i);
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public static bool load_children(List<Directories> hierarchie, string name, ref T raw_payload, bool use_install_folder = false, bool deep_load = true, bool post_process = true)
+    {
+        var new_hierarchie =
+            Instance._IJGetHierarchie(hierarchie);
+        var new_name =
+            Instance._IJGetName(name);
+
+        bool success = true;
+        for (int max_i = 0; max_i < JsonSeperateFields.Count(); max_i++)
+        {
+            var field = JsonSeperateFields[max_i];
+
+            Type interface_type = typeof(IJSONsavable<>).MakeGenericType(field.FieldType);
+            Type[] load_args_type = new Type[] { typeof(List<Directories>), typeof(string), field.FieldType.MakeByRefType(), typeof(bool), typeof(bool), typeof(bool) };
+            object[] load_args = new object[] { new_hierarchie, new_name, null, use_install_folder, deep_load, post_process };
+
+            var method = interface_type.GetMethod("load", BindingFlags.Public | BindingFlags.Static, null, load_args_type, null);
+            bool success_i = (bool)method.Invoke(null, load_args);
+            
+            field.SetValue(raw_payload, success_i ? load_args[2] : Activator.CreateInstance(field.FieldType));
+            success &= success_i;
+        }
+
+        return success;
+    }
 
-    public static bool load(List<Directories> hierarchie, string name, out T payload, bool use_install_folder = false)
+    public static bool load(List<Directories> hierarchie, string name, out T payload, bool use_install_folder = false, bool deep_load = true, bool post_process = true)
     {
         payload = default(T);
+        bool success = true;
+
         var new_hierarchie =
             Instance._IJGetHierarchie(hierarchie);
+        var new_name =
+            Instance._IJGetName(name);
 
-        string path = CreatePathToFile(out bool loadable, name, "JSON", new_hierarchie, use_install_folder);
+        string path = CreatePathToFile(out bool loadable, new_name, "JSON", new_hierarchie, use_install_folder);
         if (!loadable)
             return false;
 
-        var raw_payload = 
-            Instance._IJGetRawObject(path);
-        payload = 
-            Instance._IJPostProcess(raw_payload);
+        if (!Instance._IJGetRawObject(out T raw_payload, path))
+            return false;
+        raw_payload.name = new_name;
 
-        return true;
+        // load fields decorated with JsonSeparateAttribute and implementing IJSONsavable<> separately
+        if (deep_load
+            && !load_children(hierarchie, name, ref raw_payload, false /*use_install_folder*/))
+            success = false;
+
+        payload = post_process
+            ? Instance._IJPostProcess(raw_payload)
+            : raw_payload;
+
+        return success;
+    }
+
+    public static void delete_children(List<Directories> hierarchie, string name, bool use_install_folder = false, int skip_last_children = 0)
+    {
+        var new_hierarchie =
+            Instance._IJGetHierarchie(hierarchie);
+        var new_name =
+            Instance._IJGetName(name);
+
+        for(int i = 0; i < JsonSeperateFields.Count() - skip_last_children; i++) 
+        {
+            var field = JsonSeperateFields[i];
+
+            Type interface_type = typeof(IJSONsavable<>).MakeGenericType(field.FieldType);
+            Type[] delete_args_type = new Type[] { typeof(List<Directories>), typeof(string), typeof(bool) };
+            object[] delete_args = new object[] { new_hierarchie, new_name, use_install_folder };
+
+            var method = interface_type.GetMethod("delete", delete_args_type);
+            method.Invoke(null, delete_args);
+        }
     }
 
     public static bool delete(List<Directories> hierarchie, string name, bool use_install_folder = false)
@@ -91,11 +203,15 @@ public static bool delete(List<Directories> hierarchie, string name, bool use_in
             Instance._IJGetName(name);
 
         string path = CreatePathToFile(out bool _, new_name, "JSON", new_hierarchie, use_install_folder);
+        if (!delete(path))
+            return false;
 
-        return delete(path);
+        delete_children(hierarchie, name, use_install_folder);
+        return true;
     }
 
-    public static bool delete(string path)
+    // does not delete children!
+    private static bool delete(string path)
     {
         if (!File.Exists(path))
             return false;
@@ -104,10 +220,7 @@ public static bool delete(string path)
         return true;
     }
 
-    public bool delete()
-    {
-        return delete(path);
-    }
+    // public bool delete() => delete(hierarchie, name);
 
     #endregion MethodTemplates
 
@@ -259,6 +372,11 @@ public MMTValueDeclaration(string label, MMTTerm lhs, MMTTerm valueTp, MMTTerm v
         }
     }
 
+    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
+    public sealed class JsonSeparateAttribute : Attribute
+    {
+        public JsonSeparateAttribute() { }
+    }
 
     // TODO? /// <para>If there are public properties/variables that you do not want written to the file, decorate them with the [JsonIgnore] attribute.</para>
 
@@ -270,104 +388,32 @@ public MMTValueDeclaration(string label, MMTTerm lhs, MMTTerm valueTp, MMTTerm v
     /// <param name="filePath">The file path to write the object instance to.</param>
     /// <param name="objectToWrite">The object instance to write to the file.</param>
     /// <param name="max_depth">The depth recursion will occur. Default = 0.</param>
-    public static void WriteToJsonFile(string filePath, object objectToWrite, int max_depth = 0)
+    public static bool WriteToJsonFile(string filePath, object objectToWrite, int max_depth = 0)
     {
-        int current_depth = 0;
-
         // This tells your serializer that multiple references are okay.
         var settings = new JsonSerializerSettings
         {
             ReferenceLoopHandling = ReferenceLoopHandling.Ignore
         };
 
-        BindingFlags bindFlags =
-            BindingFlags.Instance |
-            BindingFlags.Public |
-            BindingFlags.NonPublic |
-            BindingFlags.Static;
-
         TextWriter writer = null;
         try
         {
-            string payload = RecursiveStep(objectToWrite);
+            string payload = JsonConvert.SerializeObject(objectToWrite, settings);
             writer = new StreamWriter(filePath);
             writer.Write(payload);
+            return true;
+        }
+        catch (Exception e)
+        {
+            Debug.LogError(e);
+            return false;
         }
         finally
         {
             if (writer != null)
                 writer.Close();
         }
-
-
-        // ======= local methods ======= 
-        // TODO? more stable depths (see next todo)
-        // TODO? respect IgnoreJson tags
-
-        string RecursiveStep<S>(S objectToWrite) where S : new()
-        {
-            string json;
-
-            if (current_depth >= max_depth 
-             || Type.GetTypeCode(objectToWrite.GetType()) != TypeCode.Object
-             || objectToWrite == null)
-                json = JsonConvert.SerializeObject(objectToWrite, settings/*, new JsonInheritenceConverter<object>()*/);
-            else
-            {
-                current_depth++;
-                json = IntrusiveRecursiveJsonGenerator(objectToWrite);
-                current_depth--;
-            }
-
-            return json;
-        }
-
-        string IntrusiveRecursiveJsonGenerator<S>(S objectToWrite) where S : new()
-        // private convention? more like private suggestion!
-        {
-            bool is_enum = IsEnumerableType(objectToWrite.GetType());
-
-            string json = is_enum ? "[" : "{";
-            foreach (object field in is_enum ? (objectToWrite as IEnumerable) : objectToWrite.GetType().GetFields(bindFlags))
-            {
-                object not_so_private;
-                if (is_enum)
-                {
-                    not_so_private = field;
-                }
-                else
-                {
-                    not_so_private = ((FieldInfo)field).GetValue(objectToWrite);
-                    json += ((FieldInfo)field).Name + ":";
-                }
-
-                json += RecursiveStep(not_so_private);
-
-                json += ",";
-            }
-            json = json.TrimEnd(',') + (is_enum ? "]" : "}");
-
-            return json;
-
-
-            // ======= local methods ======= 
-
-            bool IsEnumerableType(Type type)
-            {
-                if (type.IsInterface && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
-                    return true;
-
-                foreach (Type intType in type.GetInterfaces())
-                {
-                    if (intType.IsGenericType
-                        && intType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
-                    {
-                        return true;
-                    }
-                }
-                return false;
-            }
-        }
     }
 
     /// <summary>
@@ -377,14 +423,22 @@ bool IsEnumerableType(Type type)
     /// <typeparam name="T">The type of object to read from the file.</typeparam>
     /// <param name="filePath">The file path to read the object instance from.</param>
     /// <returns>Returns a new instance of the object read from the Json file.</returns>
-    public static T ReadFromJsonFile<T>(string filePath) where T : new()
+    public static bool ReadFromJsonFile<T>(out T payload, string filePath) where T : new()
     {
+        payload = default(T);
         TextReader reader = null;
+
         try
         {
             reader = new StreamReader(filePath);
             var fileContents = reader.ReadToEnd();
-            return JsonConvert.DeserializeObject<T>(fileContents/*, new JsonInheritenceConverter<object>()*/);
+            payload = JsonConvert.DeserializeObject<T>(fileContents);
+            return true;
+        }
+        catch (Exception e)
+        {
+            Debug.LogError(e);
+            return false;
         }
         finally
         {
@@ -392,37 +446,4 @@ bool IsEnumerableType(Type type)
                 reader.Close();
         }
     }
-
-    // tutorial @https://www.codeproject.com/Articles/1201466/Working-with-JSON-in-Csharp-VB#data_structure_types
-    // unused
-    // TODO: check for actual type in ReadJson
-    // TODO: avoid self-referencing-loop-error in WriteJson
-    public sealed class JsonInheritenceConverter<T> : JsonConverter
-    {
-        public override bool CanConvert(Type objectType)
-        {
-            return typeof(T).IsAssignableFrom(objectType);
-        }
-
-        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
-        {
-            JObject jo = JObject.Load(reader);
-            var element = jo.Properties().First();
-            return element.Value.ToObject(Type.GetType(element.Name));
-        }
-
-        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
-        {            
-            if (value == null)
-            {
-                serializer.Serialize(writer, null);
-                return;
-            }
-
-            writer.WriteStartObject();
-            writer.WritePropertyName(value.GetType().FullName);
-            serializer.Serialize(writer, value);
-            writer.WriteEndObject();
-        }
-    }
 }
diff --git a/Assets/Scripts/Loading/Stage.cs b/Assets/Scripts/Loading/Stage.cs
index 6a324659007245c3b0df2c4f77774d250db49db3..4da3ed348565e1148a3080cfd34c0d420a35d483 100644
--- a/Assets/Scripts/Loading/Stage.cs
+++ b/Assets/Scripts/Loading/Stage.cs
@@ -5,9 +5,13 @@
 using UnityEngine;
 using Newtonsoft.Json;
 using static CommunicationEvents;
+using System.Reflection;
 
-public class Stage
+//using static IJSONsavable<Stage>;
+
+public class Stage: IJSONsavable<Stage>
 {
+
     /// <summary> Which category this <see cref="Stage"/> should be displayed in. </summary>
     public string category = null;
     /// <summary> Where to display this <see cref="Stage"/> within a <see cref="category"/> relative to others. </summary>
@@ -16,7 +20,9 @@ public class Stage
     /// The name this <see cref="Stage"/> will be displayed with.
     /// Also defines names of save files of <see cref="player_record_list">stage progress</see>, <see cref="solution"/>
     /// </summary>
-    public string name = null;
+    public string name { set; get; } = null;
+    public string path { set; get; } = null;
+
     /// <summary> The description this <see cref="Stage"/> will be displayed with.</summary>
     public string description = null;
 
@@ -25,8 +31,9 @@ public class Stage
 
     /// <summary> Wether this <see cref="Stage"/> is located in installation folder or user data (a.k.a. !local).</summary>
     public bool use_install_folder = false;
-    /// <summary> TODO? interface </summary>
-    public List<Directories> hierarchie = null;
+
+    [JsonIgnore, JSONManager.JsonSeparate]
+    public SaveGame savegame = null;
 
     /// <summary>
     /// <see langword="true"/> iff there is at least one element in <see cref="player_record_list"/> where <see cref="PlayerRecord.solved"/> == <see langword="true"/>.
@@ -39,13 +46,17 @@ public class Stage
     /// - Key: name of file
     /// - Value: <see cref="PlayerRecord"/>
     /// </summary>
-    public Dictionary<string, PlayerRecord> player_record_list = null;
+    [JsonIgnore]
+    public Dictionary<string, PlayerRecord> player_record_list {
+        get => savegame?.player_record_list;
+        set => (savegame ??= new())
+            .player_record_list = value;
+    }
 
     /// <summary>
     /// Defining when this <see cref="Stage.player_record"/> is considered as solved.
     /// <seealso cref="FactOrganizer.DynamiclySolved(SolutionOrganizer, out List{List{string}}, out List{List{string}})"/>
     /// </summary>
-    [JsonIgnore]
     public SolutionOrganizer solution = null;
 
     /// <summary>
@@ -56,19 +67,17 @@ public class Stage
     /// </summary>
     [JsonIgnore]
     public FactOrganizer factState { 
-        get {
-            if (player_record == null)
-                return null;
-            return player_record.factState;
-        }
-        set { 
-            if (player_record == null) 
-                 player_record = new PlayerRecord(record_name);
-            player_record.factState = value; 
-        } 
+        get => player_record?.factState;
+        set => (player_record ??= new(record_name))
+            .factState = value;
     }
     /// <summary> Current Stage progress.</summary>
-    public PlayerRecord player_record = null;
+    [JsonIgnore]
+    public PlayerRecord player_record { 
+        get => savegame?.player_record;
+        set => (savegame ??= new())
+            .player_record = value;
+    }
     /// <summary> Returns a name for <see cref="player_record.name"/> which needs to be uniquified once put into <see cref="player_record_list"/> (e.g. by <see cref="push_record(double, bool) adding '_i'"/>).</summary>
     private string record_name { get { return name + "_save"; } }
 
@@ -76,17 +85,14 @@ public FactOrganizer factState {
     [JsonIgnore]
     public bool creatorMode = false;
 
-    /// @{ <summary>
-    /// TODO? interafce
-    /// </summary>
-    private string path = null;
-    private static List<Directories>
-        hierStage = new List<Directories> { Directories.Stages };
-    /// @}
-
     /// <summary> Tempory variable storing <see cref="factState"/> when <see cref="creatorMode"/> == <see langword="true"/>. </summary>
     private FactOrganizer hiddenState;
 
+    static Stage()
+    {
+        IJSONsavable<Stage>.hierarchie = new List<Directories> { Directories.Stages };
+    }
+
     /// <summary>
     /// Initiates all parameterless members. <br/>
     /// Used by <see cref="JsonConverter"/> to initate empty <c>class</c>.
@@ -115,48 +121,14 @@ public Stage(string category, int number, string name, string description, strin
         InitOOP();
     }
 
-    /// <summary>
-    /// Copy Constructor. <br/>
-    /// <seealso cref="InitOOP"/>
-    /// <seealso cref="InitFields(string, int, string, string, string, bool)"/>
-    /// </summary>
-    /// <param name="get">to be copied</param>
-    /// <param name="category">sets <see cref="category"/></param>
-    /// <param name="number">sets <see cref="number"/></param>
-    /// <param name="name">sets <see cref="name"/></param>
-    /// <param name="description">sets <see cref="description"/></param>
-    /// <param name="scene">sets <see cref="scene"/></param>
-    /// <param name="local">sets !<see cref="use_install_folder"/></param>
-    public Stage(Stage get, string category, int number, string name, string description, string scene, bool local = true)
-    {
-        InitOOP();
-        Stage cpy = new Stage();
-        // "DeepCopy" of ref-types, 'cause screw c# and ICloneable
-        load(ref cpy, get.name, null, get.use_install_folder);
-        this.hierarchie = cpy.hierarchie;
-        this.solution = cpy.solution;
-        this.player_record = cpy.player_record;
-
-        InitFields(category, number, name, description, scene, local);
 
-        hierarchie ??= new List<Directories>();
-        hierarchie.AddRange(hierStage.AsEnumerable());
-
-        player_record.load(hierarchie);
-        player_record.name = player_record.name.Replace(get.record_name, record_name);
-        player_record.store(hierarchie, false);
-
-        //this.player_record_list = cpy.player_record_list;
-        foreach (var record in cpy.player_record_list.Values)
-        {
-            record.load(hierarchie);
-            record.name = record.name.Replace(get.record_name, record_name);
-            record.store(hierarchie, false);
-            player_record_list.Add(record.name, record);
-        }
+    Stage IJSONsavable<Stage>._IJPostProcess(Stage payload)
+    {
+        payload.solution = IJSONsavable<SolutionOrganizer>.Instance._IJPostProcess(payload.solution ?? new());
+        // // savegame is saved separately
+        // payload.savegame = IJSONsavable<SaveGame>.Instance._IJPostProcess(payload.savegame ?? new());
 
-        hierarchie.RemoveRange(hierarchie.Count - hierStage.Count, hierStage.Count);
-        store(false);
+        return payload;
     }
 
     /// <summary>
@@ -184,8 +156,8 @@ public void InitFields(string category, int number, string name, string descript
     private void InitOOP()
     {
         solution = new SolutionOrganizer();
+        savegame = new();
         player_record = new PlayerRecord(record_name);
-        player_record_list = new Dictionary<string, PlayerRecord>();
     }
 
     /// <summary>
@@ -227,7 +199,7 @@ public void ClearPlay()
     /// </summary>
     public void ClearALLRecords()
     {
-        foreach (var record in player_record_list.Values.ToList())
+        foreach (var record in player_record_list.Values)
             deletet_record(record, false);
 
         player_record_list = new Dictionary<string, PlayerRecord>();
@@ -242,17 +214,12 @@ public void ClearALLRecords()
     /// <param name="b_store">iff <see langword="true"/> <see cref="store(bool)">stores</see> changes made to this <see cref="Stage"/></param>
     public void deletet_record(PlayerRecord record, bool b_store = true)
     {
-        hierarchie ??= new List<Directories>();
-        hierarchie.AddRange(hierStage.AsEnumerable());
-
-        if (record.factState != null)
-            record.factState.hardreset();
-        record.delete(hierarchie);
-        player_record_list.Remove(record.name);
+        record.factState.hardreset();
 
-        hierarchie.RemoveRange(hierarchie.Count - hierStage.Count, hierStage.Count);
-        if(b_store)
+        if (b_store) {
+            player_record_list.Remove(record.name);
             store();
+        }
     }
 
     /// <summary>
@@ -262,39 +229,24 @@ public void deletet_record(PlayerRecord record, bool b_store = true)
     /// <param name="record">to be set or <see langword="null"/></param>
     /// <returns><see langword="false"/> iff <paramref name="record"/> not found in <see cref="player_record_list"/> <br/>
     /// or <see cref="PlayerRecord.load(List<Directories>)"/> fails.</returns>
-    public bool set_record(PlayerRecord record)
+    public bool set_record(string record_index)
     {
-        hierarchie ??= new List<Directories>();
-        hierarchie.AddRange(hierStage.AsEnumerable());
+        if (record_index == null)
+            return false;
 
-        if (record != null)
-        {
-            if (!player_record_list.ContainsKey(record.name))
-            {
-                hierarchie.RemoveRange(hierarchie.Count - hierStage.Count, hierStage.Count);
-                return false;
-            }
-
-            else if (!record.load(hierarchie))
-            {
-                deletet_record(record);
-                hierarchie.RemoveRange(hierarchie.Count - hierStage.Count, hierStage.Count);
-                return false;
-            }
-        }
+        if (!player_record_list.ContainsKey(record_index))
+            return false;
 
-        player_record = record == null ? new PlayerRecord(record_name) : record.Clone(hierarchie);
+        player_record = player_record_list[record_index].Clone();
         player_record.name = record_name;
 
-        hierarchie.RemoveRange(hierarchie.Count - hierStage.Count, hierStage.Count);
-
         store(false);
-
         return true;
     }
 
     /// <summary>
     /// Adds current <see cref="player_record"/> to <see cref="player_record_list"/> incrementing <see cref="PlayerRecord.seconds"/> beforehand.
+    /// <remarks> IMPACTS SERVER PERFORMANCE: Increases number of <see cref="Fact"/>s at the Server for every <see cref="Fact"/> in current <see cref="player_record"/> </remarks>
     /// </summary>
     /// <param name="seconds_s">time in seconds to be added to <see cref="player_record.seconds"/> before pushing. <br/>
     /// Iff set to <c>-1</c> <see cref="Time.timeSinceLevelLoadAsDouble"/> will be used.</param>
@@ -305,25 +257,14 @@ public void push_record(double seconds_s = -1, bool force_push = false)
         if(!force_push && StageStatic.mode == StageStatic.Mode.Create && creatorMode)
         // store solution space
         {
-            SetMode(false);
             store(false);
-            //push_record(seconds_s, false);
-            SetMode(true);
             return;
         }
 
-        hierarchie ??= new List<Directories>();
-        hierarchie.AddRange(hierStage.AsEnumerable());
-
-        if (seconds_s == -1)
-            seconds_s = Time.timeSinceLevelLoadAsDouble;
-        player_record.seconds += seconds_s;
+        player_record.seconds += seconds_s != -1 ? seconds_s : Time.timeSinceLevelLoadAsDouble;
+        var push = player_record.Clone();
 
-        var push = player_record.Clone(hierarchie);
-
-        hierarchie.RemoveRange(hierarchie.Count - hierStage.Count, hierStage.Count);
-
-        int i = 0;
+        int i = 1;
         push.name = record_name + "_" + i.ToString();
         for (; player_record_list.ContainsKey(push.name); i++)
             push.name = record_name + "_" + i.ToString();
@@ -369,84 +310,26 @@ public void SetMode(bool create)
     /// Clears and deletes all files associated with this <see cref="Stage"/>.
     /// </summary>
     /// <param name="player_record_list_too">iff set <see langword="false"/>, all files regarding <see cref="player_record_list"/> will be spared.</param>
-    public void delete(bool player_record_list_too)
+    public void delete()
     {
-        hierarchie ??= new List<Directories>();
-        hierarchie.AddRange(hierStage.AsEnumerable());
-
-        ClearSolution();
-        ClearPlay();
-        (solution as IJSONsavable<SolutionOrganizer>).delete();
-        player_record.delete(hierarchie);
-
-        foreach (var record in player_record_list.Values.ToList())
-            record.factState.hardreset(false);
-        if (player_record_list_too)
-            ClearALLRecords();
-
-        if (File.Exists(path))
-            File.Delete(path);
-
-        hierarchie.RemoveRange(hierarchie.Count - hierStage.Count, hierStage.Count);
+        ClearAll();
+        IJSONsavable<Stage>.delete(null, name);
     }
 
     /// <summary>
     /// Stores and overwrites this <see cref="Stage"/>, <see cref="player_record"/>, every element in <see cref="player_record_list"/> and <see cref="solution"/> (no overwrite for latter if empty).
     /// </summary>
     /// <param name="reset_player">wether to clear current <see cref="player_record"/></param>
-    public void store(bool reset_player = false)
+    public void store(bool reset_player = false, bool force_stage_file = false)
     {
-        hierarchie ??= new List<Directories>();
-        hierarchie.AddRange(hierStage.AsEnumerable());
-
         player_record.name = record_name;
         if (reset_player)
             player_record = new PlayerRecord(record_name);
 
-        //if (creatorMode || StageStatic.devel)
-        {
-            string path_o = path;
-            path = CreatePathToFile(out bool exists, name, "JSON", hierarchie, use_install_folder);
-            hierarchie.RemoveRange(hierarchie.Count - hierStage.Count, hierStage.Count);
-
-            JSONManager.WriteToJsonFile(path, this, 0);
-            path = path_o;
-
-            hierarchie.AddRange(hierStage.AsEnumerable());
-            if(solution != null)
-                (solution as IJSONsavable<SolutionOrganizer>).store(hierarchie, name, use_install_folder,
-                    overwrite: solution.ValidationSet.Count > 0 && !solution.ValidationSet.Aggregate(true, (last, next) => last && next.IsEmpty()));
-        }
-
-        if (player_record != null)
-            player_record.store(hierarchie, true);
-
-        foreach (var track in player_record_list)
-            track.Value.store(hierarchie, false);
-
-        hierarchie.RemoveRange(hierarchie.Count - hierStage.Count, hierStage.Count);
-    }
-
-    /// <summary>
-    /// Loads a Stage complete using:
-    /// - <see cref="ShallowLoad(ref Stage, string, List<Directories>, bool)"/>
-    /// - <see cref="DeepLoad"/>
-    /// </summary>
-    /// \copydetails ShallowLoad(ref Stage, string, List<Directories>, bool)
-    public static bool load(ref Stage set, string name, List<Directories> hierarchie = null, bool use_install_folder = false)
-    {
-        Stage ret = new Stage();
-
-        bool loadable = ShallowLoad(ref ret, name, hierarchie, use_install_folder);
-        if (!loadable)
-            return false;
-
-        loadable = ret.DeepLoad();
-        if (!loadable)
-            return false;
-
-        set = ret;
-        return true;
+        if (force_stage_file || StageStatic.mode == StageStatic.Mode.Create)
+            (this as IJSONsavable<Stage>).store         (null, name, use_install_folder, deep_store: false);
+        else
+            (this as IJSONsavable<Stage>).store_children(null, name, false             , deep_store: true );
     }
 
     /// <summary>
@@ -456,42 +339,14 @@ public static bool load(ref Stage set, string name, List<Directories> hierarchie
     /// <param name="set">to be written in</param>
     /// <param name="path">file location</param>
     /// <returns><see langword="true"/> iff succeeded</returns>
-    public static bool ShallowLoad(ref Stage set, string path)
+    public static bool ShallowLoad(out Stage set, string path)
     {
-        if (!System.IO.File.Exists(path))
+        if (!IJSONsavable<Stage>.Instance._IJGetRawObject(out set, path))
             return false;
 
-        set = JSONManager.ReadFromJsonFile<Stage>(path);
+        set = IJSONsavable<Stage>.Instance._IJPostProcess(set);
         set.path = path;
-
-        set.hierarchie ??= new List<Directories>();
-        set.hierarchie.AddRange(hierStage.AsEnumerable());
-        //if (!set.player_record.load(set.hierarchie))
-        //    set.player_record = new PlayerRecord(set.record_name);
-        set.hierarchie.RemoveRange(set.hierarchie.Count - hierStage.Count, hierStage.Count);
-
-        return true;
-    }
-
-    /// <summary>
-    /// Determines path via <paramref name="hierarchie"/> and <paramref name="use_install_folder"/> and calls <see cref="ShallowLoad(ref Stage, string)"/>.
-    /// <seealso cref="ShallowLoad(ref Stage, string)"/>
-    /// </summary>
-    /// <param name="set">see <see cref="ShallowLoad(ref Stage, string)"/></param>
-    /// <param name="name">see <see cref="ShallowLoad(ref Stage, string)"/></param>
-    /// <param name="hierarchie">see <see cref="hierarchie"/> // TODO? Interface</param>
-    /// <param name="use_install_folder">see <see cref="use_install_folder"/></param>
-    /// <returns><see langword="true"/> iff succeeded</returns>
-    public static bool ShallowLoad(ref Stage set, string name, List<Directories> hierarchie = null, bool use_install_folder = false)
-    {
-        hierarchie ??= new List<Directories>();
-        hierarchie.AddRange(hierStage.AsEnumerable());
-
-        string path = CreatePathToFile(out bool loadable, name, "JSON", hierarchie, use_install_folder);
-        hierarchie.RemoveRange(hierarchie.Count - hierStage.Count, hierStage.Count);
-
-        if (!loadable || !ShallowLoad(ref set, path))
-            return false;
+        IJSONsavable<Stage>.load_children(null /*hierarchie*/, set.name, ref set, post_process: false);
 
         return true;
     }
@@ -502,23 +357,13 @@ public static bool ShallowLoad(ref Stage set, string name, List<Directories> hie
     /// <returns><see langword="false"/> iff <see cref="solution"/> could not be <see cref="SolutionOrganizer.load(ref SolutionOrganizer, bool, string, List<Directories>, bool)">loaded</see>.</returns>
     public bool DeepLoad()
     {
-        hierarchie ??= new List<Directories>();
-        hierarchie.AddRange(hierStage.AsEnumerable());
-
-        bool loadable;
-
-        loadable = IJSONsavable<SolutionOrganizer>.load(hierarchie, name, out solution,use_install_folder);
-        if (!loadable)
-            return false;
-
-        player_record.load(hierarchie);
-
-        hierarchie.RemoveRange(hierarchie.Count - hierStage.Count, hierStage.Count);
+        Stage cpy = this;
+        IJSONsavable<Stage>.load_children(null /*hierarchie*/, name, ref cpy);
         return true;
     }
 
     /// <summary>
-    /// Looks for saved <see cref="Stage">Stages</see> in parametised directories and calls on them <see cref="ShallowLoad(ref Stage, string)"/>.
+    /// Looks for saved <see cref="Stage">Stages</see> in parametised directories and calls on them <see cref="ShallowLoad(out Stage, string)"/>.
     /// </summary>
     /// <param name="hierarchie">see <see cref="hierarchie"/> //TODO? Interface</param>
     /// <param name="use_install_folder">see <see cref="use_install_folder"/></param>
@@ -527,25 +372,16 @@ public static Dictionary<string, Stage> Grup(List<Directories> hierarchie = null
     {
         Dictionary<string, Stage> ret = new Dictionary<string, Stage>();
 
-        hierarchie ??= new List<Directories>();
-        hierarchie.AddRange(hierStage.AsEnumerable());
-
-        string path = CreatePathToFile(out _, "", "", hierarchie, use_install_folder);
-        hierarchie.RemoveRange(hierarchie.Count - hierStage.Count, hierStage.Count);
-
-        string ending = ".JSON";
+        var new_hierarchie = IJSONsavable<Stage>.Instance._IJGetHierarchie(hierarchie);
+        string path = CreatePathToFile(out _, "", "", new_hierarchie, use_install_folder);
 
-        var info = new DirectoryInfo(path);
-        var fileInfo = info.GetFiles();
-        foreach(var file in fileInfo)
+        foreach(var file in new DirectoryInfo(path).GetFiles())
         {
-            if (0 != string.Compare(ending, 0, file.Name, file.Name.Length - ending.Length, ending.Length))
+            if (file.Extension != ".JSON")
                 continue;
 
-            Stage tmp = new Stage();
-            if (ShallowLoad(ref tmp, file.FullName))
+            if (ShallowLoad(out Stage tmp, file.FullName))
                 ret.Add(tmp.name, tmp);
-
         }
 
         return ret;
@@ -605,10 +441,38 @@ public bool CheckSolved()
 }
 
 
+public class SaveGame : IJSONsavable<SaveGame>
+{
+    public string name { get; set; }
+    public string path { get; set; }
+
+    public PlayerRecord player_record = new();
+    public Dictionary<string, PlayerRecord> player_record_list = new();
+
+    static SaveGame() 
+    {
+        IJSONsavable<SaveGame>.hierarchie = new() { Directories.SaveGames };
+    }
+    public SaveGame() { }
+
+    string IJSONsavable<SaveGame>._IJGetName(string name) => name + "_save";
+    SaveGame IJSONsavable<SaveGame>._IJPostProcess(SaveGame payload)
+    {
+        payload.player_record = IJSONsavable<PlayerRecord>.Instance._IJPostProcess(payload.player_record ?? new());
+
+        // // player_record_list entries are "PostProcess"ed when accessed/Cloned
+        //payload.player_record_list = new (payload.player_record_list.Select((v) => new KeyValuePair<string, PlayerRecord>
+        //    (v.Key, IJSONsavable<PlayerRecord>.Instance._IJPostProcess(v.Value))));
+
+        return payload;
+    }
+}
+
+
 /// <summary>
 /// Represents a save slot.
 /// </summary>
-public class PlayerRecord
+public class PlayerRecord: IJSONsavable<PlayerRecord>
 {
     /// <summary> Wether this save has solved the <see cref="Stage"/> which contains it. </summary>
     public bool solved = false;
@@ -618,13 +482,16 @@ public class PlayerRecord
     public double seconds = 0;
 
     /// <summary> Stage progress. </summary>
-    [JsonIgnore]
-    public FactOrganizer factState = null;
+    public FactOrganizer factState = new();
     /// <summary> save game file name </summary>
-    public string name = null;
+    public string name { get; set; } = null;
+
+    public string path { get; set; }
 
-    private static List<Directories>
-        hierStage = new List<Directories> { /*Directories.FactStateMachines*/ };
+    static PlayerRecord(/*static!*/)
+    {
+        IJSONsavable<PlayerRecord>.hierarchie = new List<Directories> { /*Directories.FactStateMachines*/ };
+    }
 
     /// <summary>
     /// Empty constructor for <see cref="JsonConverter"/>
@@ -640,41 +507,10 @@ public PlayerRecord(string name) {
         factState = new FactOrganizer();
     }
 
-    public void store(List<Directories> hierarchie, bool force_write)
-    {
-        hierarchie ??= new List<Directories>();
-        hierarchie.AddRange(hierStage.AsEnumerable());
-
-        if (factState != null)
-            (factState as IJSONsavable<FactOrganizer>).store(hierarchie, name, false, force_write);
-
-        hierarchie.RemoveRange(hierarchie.Count - hierStage.Count, hierStage.Count);
-    }
-
-
-    public bool load(List<Directories> hierarchie)
-    {
-        hierarchie ??= new List<Directories>();
-        hierarchie.AddRange(hierStage.AsEnumerable());
-
-        factState = new FactOrganizer(false);
-        bool loadable = IJSONsavable<FactOrganizer>.load(hierarchie, name, out factState,  false);
-        hierarchie.RemoveRange(hierarchie.Count - hierStage.Count, hierStage.Count);
-        if (!loadable) {
-            return false;
-        }
-
-        return true;
-    }
-
-    public void delete(List<Directories> hierarchie)
+    PlayerRecord IJSONsavable<PlayerRecord>._IJPostProcess(PlayerRecord payload)
     {
-        hierarchie ??= new List<Directories>();
-        hierarchie.AddRange(hierStage.AsEnumerable());
-
-        IJSONsavable<FactOrganizer>.delete(hierarchie, name, false);
-
-        hierarchie.RemoveRange(hierarchie.Count - hierStage.Count, hierStage.Count);
+        payload.factState = IJSONsavable<FactOrganizer>.Instance._IJPostProcess(payload.factState);
+        return payload;
     }
 
     /// <summary>
@@ -682,21 +518,15 @@ public void delete(List<Directories> hierarchie)
     /// </summary>
     /// <param name="hierarchie">// TODO:</param>
     /// <returns>a copied <see cref="PlayerRecord"/></returns>
-    public PlayerRecord Clone(List<Directories> hierarchie)
+    public PlayerRecord Clone()
     {
-        this.store(hierarchie, true);
-
-        hierarchie ??= new List<Directories>();
-        hierarchie.AddRange(hierStage.AsEnumerable());
-
         var ret = new PlayerRecord(this.name)
         {
             solved = this.solved,
             seconds = this.seconds
         };
-        ret.load(hierarchie);
+        ret.factState = FactOrganizer.ReInitializeFactOrganizer<FactOrganizer>(this.factState, false, out _);
 
-        hierarchie.RemoveRange(hierarchie.Count - hierStage.Count, hierStage.Count);
         return ret;
     }
 }
\ No newline at end of file
diff --git a/Assets/Scripts/StageBehaviour.cs b/Assets/Scripts/StageBehaviour.cs
index a508070d7aea727ab411f655155cbf4cea0e74aa..d77a56253e113b8524d7527d9f93bf9c5529a0ff 100644
--- a/Assets/Scripts/StageBehaviour.cs
+++ b/Assets/Scripts/StageBehaviour.cs
@@ -22,8 +22,8 @@ void Start()
     private void OnDestroy()
     {
         StageStatic.SetMode(Mode.Play); // no Mode.Create
-        StageStatic.stage.solution.hardreset();
-        StageStatic.stage.factState.hardreset();
+        StageStatic.stage.solution.hardreset(invoke_event: false);
+        StageStatic.stage.factState.hardreset(invoke_event: false);
     }
 
     /// <summary>
diff --git a/Assets/Scripts/StageStatic.cs b/Assets/Scripts/StageStatic.cs
index 49c0d653d0149c778bd088ea1bfb11830c4f09d0..1af549119cdc99b3c5dfe155c9aeddcbbc3b6937 100644
--- a/Assets/Scripts/StageStatic.cs
+++ b/Assets/Scripts/StageStatic.cs
@@ -64,8 +64,6 @@ public static Stage stage {
 
             (local_stage ? StageLocal : StageOfficial).Remove(current_name);
             (local_stage ? StageLocal : StageOfficial).Add(current_name, value);
-
-            value.store();
         }
     }
 
@@ -234,11 +232,8 @@ public static StageErrorStruct LoadNewStage(string category, int id, string name
         if (!ret.pass)
             return ret;
 
-        stage = new Stage(category, id, name, description, scene, true)
-        {
-            creatorMode = true
-        };
-        stage.store();
+        stage = new Stage(category, id, name, description, scene, true);
+        stage.store(force_stage_file: true);
 
         LoadCreate();
         return ret;
@@ -294,7 +289,7 @@ public static bool ContainsNumber(string category, int i, bool local)
     }
 
     /// <summary>
-    /// Looks for and initial loads (see <see cref="Stage.ShallowLoad(ref Stage, string)"/>) <see cref="Stage">Stages</see> in <see cref="local_stage"/> and !<see cref="local_stage"/>.
+    /// Looks for and initial loads (see <see cref="Stage.ShallowLoad(out Stage, string)"/>) <see cref="Stage">Stages</see> in <see cref="local_stage"/> and !<see cref="local_stage"/>.
     /// </summary>
     public static void ShallowLoadStages()
     {
@@ -326,12 +321,12 @@ public static Stage GetStage(string name, bool local)
 
     /// <summary>
     /// Deletes a <see cref="Stage"/> and all its associated files (including save games).
-    /// <seealso cref="Stage.delete(bool)"/>
+    /// <seealso cref="Stage.delete()"/>
     /// </summary>
     /// <param name="stage">to be deleted</param>
     public static void Delete(Stage stage)
     {
-        GetStage(stage.name, !stage.use_install_folder).delete(true);
+        GetStage(stage.name, !stage.use_install_folder).delete();
         (!stage.use_install_folder ? StageLocal : StageOfficial).Remove(stage.name);
     }
 
@@ -379,13 +374,13 @@ public static bool LoadInitStage(bool restore_session, GameObject gameObject = n
         else
         {
             stage.ResetPlay();
-            if(mode == Mode.Create) // block saving "player" progress
-                stage.player_record.seconds = -1;
+            //if(mode == Mode.Create) // block saving "player" progress
+            //    stage.player_record.seconds = -1;
         }
 
         if(gameObject != null)
             gameObject.UpdateTagActive("DevelopingMode", mode == Mode.Create);
-        SetMode(stage.creatorMode ? Mode.Create : Mode.Play);
+        SetMode(mode);
         return true;
     }
 
diff --git a/Assets/Scripts/UI/MainMenue/CollapsableStage/CollapsableStage.cs b/Assets/Scripts/UI/MainMenue/CollapsableStage/CollapsableStage.cs
index 0c63522aff41d184a843f31efeaed48db2d2b3f4..9f9b04d767553b05e137717d1bf1c4988c034e49 100644
--- a/Assets/Scripts/UI/MainMenue/CollapsableStage/CollapsableStage.cs
+++ b/Assets/Scripts/UI/MainMenue/CollapsableStage/CollapsableStage.cs
@@ -72,7 +72,7 @@ public void DrawChildren()
             // button Action to load a record
             UnityAction loadRecord = delegate () {
                 // redraw this, when unable to find record
-                if (!stage.set_record(stage.player_record_list[index])) {
+                if (!stage.set_record(index)) {
                     this.Init();
                     return;
                 }
diff --git a/Assets/Scripts/UI/MainMenue/PageLoader/EditLoader.cs b/Assets/Scripts/UI/MainMenue/PageLoader/EditLoader.cs
index c1a3491e90f31d9dd1cbcf9159868ba6ab488068..139c8e1a8a71597089b96aa90b8dc936bbb3fe67 100644
--- a/Assets/Scripts/UI/MainMenue/PageLoader/EditLoader.cs
+++ b/Assets/Scripts/UI/MainMenue/PageLoader/EditLoader.cs
@@ -63,11 +63,15 @@ private bool _Clone(bool overwrite)
             return false;
         }
 
-        Stage new_stage = new Stage(original_stage, category, id, name, description, scene, true);
+        IJSONsavable<Stage>.load(null /*original_stage.hierarchie*/, original_stage.name, out Stage new_stage, original_stage.use_install_folder, true);
+        new_stage.InitFields(category, id, name, description, scene, true);
+
         if (!overwrite)
             new_stage.ResetSaves();
 
         StageStatic.stage = new_stage;
+        new_stage.store(force_stage_file: true );
+        new_stage.store(force_stage_file: false);
         return true;
     }
 
diff --git a/Assets/Stages/FactStateMachines.meta b/Assets/Stages/FactStateMachines.meta
deleted file mode 100644
index debf5ea4e5e4c133644ea1901cafeceec3d4ecba..0000000000000000000000000000000000000000
--- a/Assets/Stages/FactStateMachines.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: 7d43c521d7312964cb72014365bd183e
-folderAsset: yes
-DefaultImporter:
-  externalObjects: {}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Assets/Stages/FactStateMachines/TechDemo A.JSON b/Assets/Stages/FactStateMachines/TechDemo A.JSON
deleted file mode 100644
index 44fda086c9377bf6388b2b00c979f9b52a24565d..0000000000000000000000000000000000000000
--- a/Assets/Stages/FactStateMachines/TechDemo A.JSON	
+++ /dev/null
@@ -1 +0,0 @@
-{"ValidationSet":[{"MasterIDs":["http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2844"],"SolutionIndex":[],"RelationIndex":[],"ComparerString":"LineFactHightDirectionComparer"}],"FactDict":{"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2842":{"s_type":"PointFact","Point":{"x":0.0,"y":0.0,"z":0.0,"magnitude":0.0,"sqrMagnitude":0.0},"Normal":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2842","Label":"A","hasCustomLabel":false,"LabelId":1},"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2843":{"s_type":"PointFact","Point":{"x":0.0,"y":6.0,"z":0.0,"normalized":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"magnitude":6.0,"sqrMagnitude":36.0},"Normal":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2843","Label":"B","hasCustomLabel":false,"LabelId":2},"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2844":{"s_type":"LineFact","Distance":6.0,"Pid1":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2842","Pid2":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2843","Dir":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2844","Label":"[AB]","hasCustomLabel":false,"LabelId":0}},"MetaInf":{"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2842":{"workflow_id":0,"active":true},"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2843":{"workflow_id":1,"active":true},"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2844":{"workflow_id":2,"active":true}},"Workflow":[{"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2842","samestep":false,"steplink":3,"creation":true},{"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2843","samestep":true,"steplink":0,"creation":true},{"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2844","samestep":true,"steplink":0,"creation":true}],"marker":3,"worksteps":1,"backlog":0,"soft_resetted":false,"invoke":false,"MaxLabelId":2,"UnusedLabelIds":[],"path":null}
\ No newline at end of file
diff --git a/Assets/Stages/FactStateMachines/TechDemo A.JSON.meta b/Assets/Stages/FactStateMachines/TechDemo A.JSON.meta
deleted file mode 100644
index 7a7991a639facce43bdf9d684bd967ade8d15383..0000000000000000000000000000000000000000
--- a/Assets/Stages/FactStateMachines/TechDemo A.JSON.meta	
+++ /dev/null
@@ -1,7 +0,0 @@
-fileFormatVersion: 2
-guid: b9f66b56bf429ad42a19258696330fa3
-TextScriptImporter:
-  externalObjects: {}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Assets/Stages/FactStateMachines/TechDemo B.JSON b/Assets/Stages/FactStateMachines/TechDemo B.JSON
deleted file mode 100644
index 41312506fd24bfceb0dcf18c3545b1225e4022ac..0000000000000000000000000000000000000000
--- a/Assets/Stages/FactStateMachines/TechDemo B.JSON	
+++ /dev/null
@@ -1 +0,0 @@
-{"ValidationSet":[{"MasterIDs":["http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2847"],"SolutionIndex":[],"RelationIndex":[],"ComparerString":"LineFactHightDirectionComparer"},{"MasterIDs":["http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2847"],"SolutionIndex":[],"RelationIndex":[],"ComparerString":"LineSpanningOverRiverWorldComparer"},{"MasterIDs":[],"SolutionIndex":[1],"RelationIndex":[0],"ComparerString":"LineFactHightComparer"}],"FactDict":{"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2845":{"s_type":"PointFact","Point":{"x":0.0,"y":0.0,"z":0.0,"magnitude":0.0,"sqrMagnitude":0.0},"Normal":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2845","Label":"A","hasCustomLabel":false,"LabelId":1},"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2846":{"s_type":"PointFact","Point":{"x":0.0,"y":6.0,"z":0.0,"normalized":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"magnitude":6.0,"sqrMagnitude":36.0},"Normal":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2846","Label":"B","hasCustomLabel":false,"LabelId":2},"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2847":{"s_type":"LineFact","Distance":6.0,"Pid1":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2845","Pid2":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2846","Dir":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2847","Label":"[AB]","hasCustomLabel":false,"LabelId":0}},"MetaInf":{"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2845":{"workflow_id":0,"active":true},"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2846":{"workflow_id":1,"active":true},"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2847":{"workflow_id":2,"active":true}},"Workflow":[{"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2845","samestep":false,"steplink":3,"creation":true},{"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2846","samestep":true,"steplink":0,"creation":true},{"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2847","samestep":true,"steplink":0,"creation":true}],"marker":3,"worksteps":1,"backlog":0,"soft_resetted":false,"invoke":false,"MaxLabelId":2,"UnusedLabelIds":[],"path":null}
\ No newline at end of file
diff --git a/Assets/Stages/FactStateMachines/TechDemo B.JSON.meta b/Assets/Stages/FactStateMachines/TechDemo B.JSON.meta
deleted file mode 100644
index 8c36ca7bb7a99b5398b33cb4302eff4b77c8eefe..0000000000000000000000000000000000000000
--- a/Assets/Stages/FactStateMachines/TechDemo B.JSON.meta	
+++ /dev/null
@@ -1,7 +0,0 @@
-fileFormatVersion: 2
-guid: 6c3c72bfe0bce2d4dbc7bfa537c6c2bf
-TextScriptImporter:
-  externalObjects: {}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Assets/Stages/TechDemo A.JSON b/Assets/Stages/TechDemo A.JSON
index ac6246f475c836f183a48e3d7a577e7a77bb3a36..11ae46691be69ffd3f5ef11855d6131515950ae6 100644
--- a/Assets/Stages/TechDemo A.JSON	
+++ b/Assets/Stages/TechDemo A.JSON	
@@ -1 +1 @@
-{"category":"Demo Category","number":0,"name":"TechDemo A","description":"Tree Stage","scene":"RiverWorld","use_install_folder":true,"hierarchie":[],"player_record_list":{},"player_record":{"solved":false,"date":-8585436724597716289,"seconds":0.0,"name":"TechDemo A_save"}}
\ No newline at end of file
+{"category":"Demo Category","number":1,"description":"Tree Stage","scene":"RiverWorld","use_install_folder":true,"solution":{"ValidationSet":[{"MasterIDs":["http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2885"],"SolutionIndex":[],"RelationIndex":[],"ComparerString":"LineFactHightDirectionComparer"}],"FactDict":{"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2883":{"s_type":"PointFact","Point":{"x":0.0,"y":0.0,"z":0.0,"magnitude":0.0,"sqrMagnitude":0.0},"Normal":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2883","Label":"A","hasCustomLabel":false,"LabelId":1},"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2884":{"s_type":"PointFact","Point":{"x":0.0,"y":6.0,"z":0.0,"normalized":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"magnitude":6.0,"sqrMagnitude":36.0},"Normal":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2884","Label":"B","hasCustomLabel":false,"LabelId":2},"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2885":{"s_type":"LineFact","Distance":6.0,"Pid1":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2883","Pid2":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2884","Dir":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2885","Label":"[AB]","hasCustomLabel":false,"LabelId":0}},"MetaInf":{"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2883":{"workflow_id":0,"active":true},"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2884":{"workflow_id":1,"active":true},"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2885":{"workflow_id":2,"active":true}},"Workflow":[{"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2883","samestep":false,"steplink":3,"creation":true},{"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2884","samestep":true,"steplink":0,"creation":true},{"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2885","samestep":true,"steplink":0,"creation":true}],"marker":3,"worksteps":1,"backlog":0,"soft_resetted":false,"invoke":true,"MaxLabelId":2,"UnusedLabelIds":[],"name":null,"path":null},"name":"TechDemo A","path":null}
\ No newline at end of file
diff --git a/Assets/Stages/TechDemo B.JSON b/Assets/Stages/TechDemo B.JSON
index c52c06871b52696cb33544ed4b9b16c3353139a2..93bff977f35c30d27eecab9672864d64513b3a64 100644
--- a/Assets/Stages/TechDemo B.JSON	
+++ b/Assets/Stages/TechDemo B.JSON	
@@ -1 +1 @@
-{"category":"Demo Category","number":0,"name":"TechDemo B","description":"River Stage","scene":"RiverWorld","use_install_folder":true,"hierarchie":[],"player_record_list":{},"player_record":{"solved":false,"date":-8585436724595934380,"seconds":0.0,"name":"TechDemo B_save"}}
\ No newline at end of file
+{"category":"Demo Category","number":2,"description":"River Stage","scene":"RiverWorld","use_install_folder":true,"solution":{"ValidationSet":[{"MasterIDs":["http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2888"],"SolutionIndex":[],"RelationIndex":[],"ComparerString":"LineFactHightDirectionComparer"},{"MasterIDs":["http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2888"],"SolutionIndex":[],"RelationIndex":[],"ComparerString":"LineSpanningOverRiverWorldComparer"},{"MasterIDs":[],"SolutionIndex":[1],"RelationIndex":[0],"ComparerString":"LineFactHightComparer"}],"FactDict":{"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2886":{"s_type":"PointFact","Point":{"x":0.0,"y":0.0,"z":0.0,"magnitude":0.0,"sqrMagnitude":0.0},"Normal":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2886","Label":"A","hasCustomLabel":false,"LabelId":1},"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2887":{"s_type":"PointFact","Point":{"x":0.0,"y":6.0,"z":0.0,"normalized":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"magnitude":6.0,"sqrMagnitude":36.0},"Normal":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2887","Label":"B","hasCustomLabel":false,"LabelId":2},"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2888":{"s_type":"LineFact","Distance":6.0,"Pid1":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2886","Pid2":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2887","Dir":{"x":0.0,"y":1.0,"z":0.0,"magnitude":1.0,"sqrMagnitude":1.0},"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2888","Label":"[AB]","hasCustomLabel":false,"LabelId":0}},"MetaInf":{"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2886":{"workflow_id":0,"active":true},"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2887":{"workflow_id":1,"active":true},"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2888":{"workflow_id":2,"active":true}},"Workflow":[{"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2886","samestep":false,"steplink":3,"creation":true},{"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2887","samestep":true,"steplink":0,"creation":true},{"Id":"http://mathhub.info/FrameIT/frameworld/integrationtests?SampleSituationSpace/Root?fact2888","samestep":true,"steplink":0,"creation":true}],"marker":3,"worksteps":1,"backlog":0,"soft_resetted":false,"invoke":true,"MaxLabelId":2,"UnusedLabelIds":[],"name":null,"path":null},"name":"TechDemo B","path":null}
\ No newline at end of file