diff --git a/Assets/Scripts/GenerateDemoFiles.cs b/Assets/Scripts/GenerateDemoFiles.cs
index 252a0ca7521dbf672742fc79594b149bcf2ccc3e..6203e440bfde7e9fdfea30060404e040bd022a64 100644
--- a/Assets/Scripts/GenerateDemoFiles.cs
+++ b/Assets/Scripts/GenerateDemoFiles.cs
@@ -46,11 +46,11 @@ public static void GenerateDemoA()
             buttom = new PointFact(Vector3.zero, Vector3.up, StageStatic.stage.solution),
             top = new PointFact(Vector3.zero + Vector3.up * minimalSolutionHight, Vector3.up, StageStatic.stage.solution);
 
-        StageStatic.stage.solution.Add(buttom, out _, false, null);
-        StageStatic.stage.solution.Add(top, out _, true, null);
+        StageStatic.stage.solution.Add(buttom, out _, false, null, null);
+        StageStatic.stage.solution.Add(top, out _, true, null, null);
 
         LineFact target = new LineFact(buttom.Id, top.Id, StageStatic.stage.solution);
-        var target_Id = StageStatic.stage.solution.Add(target, out _, true, null);
+        var target_Id = StageStatic.stage.solution.Add(target, out _, true, null, null);
 
         // Set Solution
         StageStatic.stage.solution.ValidationSet =
@@ -92,11 +92,11 @@ public static void GenerateDemoB()
             buttom = new PointFact(Vector3.zero, Vector3.up, StageStatic.stage.solution),
             top = new PointFact(Vector3.zero + Vector3.up * minimalSolutionHight, Vector3.up, StageStatic.stage.solution);
 
-        StageStatic.stage.solution.Add(buttom, out _, false, null);
-        StageStatic.stage.solution.Add(top, out _, true, null);
+        StageStatic.stage.solution.Add(buttom, out _, false, null, null);
+        StageStatic.stage.solution.Add(top, out _, true, null, null);
 
         LineFact target = new LineFact(buttom.Id, top.Id, StageStatic.stage.solution);
-        var target_Id = StageStatic.stage.solution.Add(target, out _, true, null);
+        var target_Id = StageStatic.stage.solution.Add(target, out _, true, null, null);
 
         // Set Solution
         StageStatic.stage.solution.ValidationSet =
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/FactManager.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactManager.cs
index 158544732849984b8a9373f203a73cb750ca3be2..f096094ef1261ce2f4e9973b283c520cf0a140a2 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/FactManager.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/FactManager.cs
@@ -1,4 +1,5 @@
-using UnityEngine;
+using System;
+using UnityEngine;
 
 /// <summary>
 /// Initiates named <see cref="Fact"/> and adds it to <see cref="StageStatic.stage.factState"/>
@@ -15,44 +16,57 @@ public static class FactManager
     /// <param name="fact">to be added</param>
     /// <param name="exists"><c>true</c> iff <paramref name="fact"/> already has a equivalent counterpart in <paramref name="fact._Facts"/></param>
     /// \copydetails FactManager
-    public static Fact AddFactIfNotFound(Fact fact, out bool exists, bool samestep)
+    public static Fact AddFactIfNotFound(Fact fact, out bool exists, bool samestep, Type gadget, string scroll_label)
     {
-        return StageStatic.stage.factState[StageStatic.stage.factState.Add(fact, out exists, samestep, GadgetManager.activeGadget.GetType())];
+        return StageStatic.stage.factState[
+            StageStatic.stage.factState.Add(
+                fact, out exists, samestep
+                , gadget ?? (scroll_label == null ? GadgetManager.activeGadget.GetType() : null)
+                , scroll_label
+            )];
     }
 
     /// \copybrief FactManager <summary></summary>
     /// <param name="hit"><c>RaycastHit</c> where and how (orientation) to spawn <see cref="PointFact"/></param>
     /// \copydetails FactManager
-    public static PointFact AddPointFact(RaycastHit hit, bool samestep = false)
+    public static PointFact AddPointFact(RaycastHit hit, bool samestep = false, Type gadget = null, string scroll_label = null)
     {
-        return (PointFact) AddFactIfNotFound(new PointFact(hit.point, hit.normal, StageStatic.stage.factState), out _, samestep);
+        return (PointFact) AddFactIfNotFound(
+            new PointFact(hit.point, hit.normal, StageStatic.stage.factState)
+            , out _, samestep, gadget, scroll_label);
     }
 
     /// \copybrief FactManager <summary></summary>
     /// <param name="point">where to spawn <see cref="PointFact"/></param>
     /// <param name="normal">how (orientation) to spawn <see cref="PointFact"/></param>
     /// \copydetails FactManager
-    public static PointFact AddPointFact(Vector3 point, Vector3 normal, bool samestep = false)
+    public static PointFact AddPointFact(Vector3 point, Vector3 normal, bool samestep = false, Type gadget = null, string scroll_label = null)
     {
-        return (PointFact) AddFactIfNotFound(new PointFact(point, normal, StageStatic.stage.factState), out _, samestep);
+        return (PointFact) AddFactIfNotFound(
+            new PointFact(point, normal, StageStatic.stage.factState)
+            , out _, samestep, gadget, scroll_label);
     }
 
     /// \copybrief FactManager <summary></summary>
     /// <param name="pid"><see cref="Fact.Id"/> of <see cref="PointFact"/> which lies on <paramref name="lid"/></param>
     /// <param name="lid"><see cref="Fact.Id"/> of <see cref="LineFact"/> on which <paramref name="pid"/> lies</param>
     /// \copydetails FactManager
-    public static OnLineFact AddOnLineFact(string pid, string lid, bool samestep = false)
+    public static OnLineFact AddOnLineFact(string pid, string lid, bool samestep = false, Type gadget = null, string scroll_label = null)
     {
-        return (OnLineFact)AddFactIfNotFound(new OnLineFact(pid, lid, StageStatic.stage.factState), out _, samestep);
+        return (OnLineFact)AddFactIfNotFound(
+            new OnLineFact(pid, lid, StageStatic.stage.factState)
+            , out _, samestep, gadget, scroll_label);
     }
 
     /// \copybrief FactManager <summary></summary>
     /// <param name="pid1"><see cref="Fact.Id"/> of first <see cref="PointFact"/> defining a <see cref="LineFact"/></param>
     /// <param name="pid2"><see cref="Fact.Id"/> of second <see cref="PointFact"/> defining a <see cref="LineFact"/></param>
     /// \copydetails FactManager
-    public static LineFact AddLineFact(string pid1, string pid2, bool samestep = false)
+    public static LineFact AddLineFact(string pid1, string pid2, bool samestep = false, Type gadget = null, string scroll_label = null)
     {
-        return (LineFact)AddFactIfNotFound(new LineFact(pid1, pid2, StageStatic.stage.factState), out _, samestep);
+        return (LineFact)AddFactIfNotFound(
+            new LineFact(pid1, pid2, StageStatic.stage.factState)
+            , out _, samestep, gadget, scroll_label);
     }
 
     /// \copybrief FactManager
@@ -62,9 +76,12 @@ public static LineFact AddLineFact(string pid1, string pid2, bool samestep = fal
     /// <param name="pid1"><see cref="Fact.Id"/> of first <see cref="PointFact"/> defining a <see cref="RayFact"/></param>
     /// <param name="pid2"><see cref="Fact.Id"/> of second <see cref="PointFact"/> defining a <see cref="RayFact"/></param>
     /// \copydetails FactManager
-    public static RayFact AddRayFact(string pid1, string pid2, bool samestep = false)
+    public static RayFact AddRayFact(string pid1, string pid2, bool samestep = false, Type gadget = null, string scroll_label = null)
     {
-        RayFact rayFact = (RayFact)AddFactIfNotFound(new RayFact(pid1, pid2, StageStatic.stage.factState), out bool exists, samestep);
+        RayFact rayFact = (RayFact)AddFactIfNotFound(
+            new RayFact(pid1, pid2, StageStatic.stage.factState)
+            , out bool exists, samestep, gadget, scroll_label);
+
         if (exists)
             return rayFact;
 
@@ -79,7 +96,8 @@ void AddHitIfOnLine(RaycastHit hit)
         {
             if (Math3d.IsPointApproximatelyOnLine(rayP1.Point, rayFact.Dir, hit.transform.position))
             {
-                AddOnLineFact(hit.transform.gameObject.GetComponent<FactObject>().URI, rayFact.Id, true);
+                AddOnLineFact(
+                    hit.transform.gameObject.GetComponent<FactObject>().URI, rayFact.Id, true, gadget, scroll_label);
             }
         }
 
@@ -90,8 +108,8 @@ void AddHitIfOnLine(RaycastHit hit)
             AddHitIfOnLine(hit);
 
         // for good measure
-        AddOnLineFact(rayFact.Pid1, rayFact.Id, true);
-        AddOnLineFact(rayFact.Pid2, rayFact.Id, true);
+        AddOnLineFact(rayFact.Pid1, rayFact.Id, true, gadget, scroll_label);
+        AddOnLineFact(rayFact.Pid2, rayFact.Id, true, gadget, scroll_label);
 
         return rayFact;
     }
@@ -101,9 +119,11 @@ void AddHitIfOnLine(RaycastHit hit)
     /// <param name="pid2"><see cref="Fact.Id"/> of second <see cref="PointFact"/> defining a <see cref="AngleFact"/></param>
     /// <param name="pid3"><see cref="Fact.Id"/> of third <see cref="PointFact"/> defining a <see cref="AngleFact"/></param>
     /// \copydetails FactManager
-    public static AngleFact AddAngleFact(string pid1, string pid2, string pid3, bool samestep = false)
+    public static AngleFact AddAngleFact(string pid1, string pid2, string pid3, bool samestep = false, Type gadget = null, string scroll_label = null)
     {
-        return (AngleFact)AddFactIfNotFound(new AngleFact(pid1, pid2, pid3, StageStatic.stage.factState), out _, samestep);
+        return (AngleFact)AddFactIfNotFound(
+            new AngleFact(pid1, pid2, pid3, StageStatic.stage.factState)
+            , out _, samestep, gadget, scroll_label);
     }
 
 }
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/FactOrganizer.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactOrganizer.cs
index 60c07fb8b33da4f40c92db23255d84a270ca84f3..6fac2c6c4c4e50eacf77e4da49e92f37aa66d485 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/FactOrganizer.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/FactOrganizer.cs
@@ -173,22 +173,33 @@ protected internal struct meta
 
         /// <summary>
         /// keeps track with wich <see cref="Gadget"/> the <see cref="Fact"/> is created
+        /// <c>null</c> iff its not the case
         /// </summary>
         public Type gadget {
             get => _gadget;
-            set => _gadget = Gadget.GadgetTypes.Contains(value) ? value : typeof(Gadget.UndefinedGadget);
+            set => _gadget = 
+                value == null ? null : 
+                Gadget.GadgetTypes.Contains(value) ? value : 
+                typeof(Gadget.UndefinedGadget);
         }
         private Type _gadget;
 
+        /// <summary>
+        /// keeps track with wich <see cref="Scroll"/> the <see cref="Fact"/> is created
+        /// <c>null</c> iff its not the case
+        /// </summary>
+        public string scroll_label;
+
         /// <summary>
         /// Initiator
         /// </summary>
         /// <param name="workflow_id">sets <see cref="workflow_id"/></param>
         /// <param name="active">sets <see cref="active"/></param>
-        public meta(int workflow_id, bool active, Type gadget)
+        public meta(int workflow_id, bool active, Type gadget, string scroll_label)
         {
             this.workflow_id = workflow_id;
             this.active = active;
+            this.scroll_label = scroll_label;
             _gadget = null; //Compiler Restriction
             this.gadget = gadget;
         }
@@ -265,7 +276,7 @@ public static T ReInitializeFactOrganizer<T>
                     old_to_new.Add(sn.Id, add.Id);
                 }
 
-                target.Add(add, out _, sn.samestep, source.MetaInf[sn.Id].gadget);
+                target.Add(add, out _, sn.samestep, source.MetaInf[sn.Id].gadget, source.MetaInf[sn.Id].scroll_label);
             }
             else if (old_to_new.ContainsKey(sn.Id))
             // Remove
@@ -417,7 +428,7 @@ private void PruneWorkflow()
     /// <param name="samestep">set <c>true</c> if <see cref="Fact"/> creation happens as a subsequent/ consequent step of multiple <see cref="Fact"/> creations and/or deletions, 
     /// and you whish that these are affected by a single <see cref="undo"/>/ <see cref="redo"/> step</param>
     /// <returns><see cref="Fact.Id"/> of <paramref name="value"/> or <see cref="FindEquivalent(Fact, out string, out bool)">found</see> <see cref="Fact"/> iff <paramref name="exists"/>==<c>true</c></returns>
-    public string Add(Fact value, out bool exists, bool samestep, Type gadget)
+    public string Add(Fact value, out bool exists, bool samestep, Type gadget, string scroll_label)
     {
         soft_resetted = false;
 #pragma warning disable IDE0018 // Inlinevariablendeklaration
@@ -438,7 +449,7 @@ public string Add(Fact value, out bool exists, bool samestep, Type gadget)
                 zombie.creation = false; // this meta entry will be deleted, but will not trigger deletion
                 Workflow[MetaInf[key].workflow_id] = zombie;
                 // set new init location
-                MetaInf[key] = new meta(marker, true, gadget);
+                MetaInf[key] = new meta(marker, true, gadget, scroll_label);
             }
             // zombies are undead!
             else if (MetaInf[key].active)
@@ -451,7 +462,7 @@ public string Add(Fact value, out bool exists, bool samestep, Type gadget)
         {
             key = value.Id;
             FactDict.Add(key, value);
-            MetaInf.Add(key, new meta(marker, true, gadget));
+            MetaInf.Add(key, new meta(marker, true, gadget, scroll_label));
         }
 
         WorkflowAdd(new stepnote(key, samestep, true, this));
@@ -822,6 +833,13 @@ public bool DynamiclySolved(
     }
 
     public IEnumerable<Type> GetUsedGadgets()
-        => MetaInf.Values.Where(inf => inf.active).Select(inf => inf.gadget);
+        => MetaInf.Values.Where(inf => inf.active & inf.gadget != null).Select(inf => inf.gadget).Distinct();
+
+    public int GetNumberOfGadgets() => GetUsedGadgets().Count();
+    
+    public IEnumerable<string> GetUsedScrolls()
+        => MetaInf.Values.Where(inf => inf.active && inf.scroll_label != null).Select(inf => inf.scroll_label).Distinct();
+
+    public int GetNumberOfScrolls() => GetUsedScrolls().Count();
 
 }
\ No newline at end of file
diff --git a/Assets/Scripts/InventoryStuff/DisplayScrolls.cs b/Assets/Scripts/InventoryStuff/DisplayScrolls.cs
index fbd9abf21f1faa7448ff70b8ce88481b46114a79..ae6a58960e4f9fcd1a446c3ac362f91aef3b1825 100644
--- a/Assets/Scripts/InventoryStuff/DisplayScrolls.cs
+++ b/Assets/Scripts/InventoryStuff/DisplayScrolls.cs
@@ -10,13 +10,11 @@ public class DisplayScrolls : MonoBehaviour
     public string preferredStartScrollName;
     public int tryScrollListTimes = 2;
 
-    public List<Scroll> scrolls;
+    static public List<Scroll> AvailableScrolls;
     public GameObject[] ScrollButtons;
     public GameObject ScrollPrefab;
     public GameObject DetailScreen;
 
-
-
     public int x_Start;
     public int y_Start;
     public int X_Pacece_Between_Items;
@@ -24,23 +22,11 @@ public class DisplayScrolls : MonoBehaviour
     public int number_of_Column;
 
 
-    // Update is called once per frame
-    void Update()
-    {
-
-    }
-
-
     public Vector3 GetPosition(int i)
     {
         return new Vector3(x_Start + (X_Pacece_Between_Items * (i % number_of_Column)), y_Start + (-y_Pacece_Between_Items * (i / number_of_Column)), 0f);
     }
 
-    /*  [System.Serializable]
-      class ScrollArrayWrapper {
-          public Scroll[] Scrolls;
-      };*/
-
     // Start is called before the first frame update
     void Start()
     {
@@ -106,22 +92,20 @@ IEnumerator getScrollsfromServer()
 
     void BuildScrolls(string jsonString)
     {
-        var scrolls = Scroll.FromJSON(jsonString);
-        this.scrolls = scrolls;
-        ScrollButtons = new GameObject[this.scrolls.Count];
+        AvailableScrolls = Scroll.FromJSON(jsonString);
+        ScrollButtons = new GameObject[AvailableScrolls.Count];
         //Build Selection-GUI of Scrolls
-        for (int i = 0; i < this.scrolls.Count; i++)
+        for (int i = 0; i < AvailableScrolls.Count; i++)
         {
-
             var obj = Instantiate(ScrollPrefab, Vector3.zero, Quaternion.identity, transform);
             obj.GetComponent<RectTransform>().localPosition = GetPosition(i);
-            obj.GetComponent<ScrollClickedScript>().scroll = this.scrolls[i];
+            obj.GetComponent<ScrollClickedScript>().scroll = AvailableScrolls[i];
             obj.GetComponent<ScrollClickedScript>().DetailScreen = this.DetailScreen;
-            obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = this.scrolls[i].label;
+            obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = AvailableScrolls[i].label;
             ScrollButtons[i] = obj;
         }
 
-        Scroll preferredStartScroll = this.scrolls.Find(x => x.label.Equals(preferredStartScrollName));
+        Scroll preferredStartScroll = AvailableScrolls.Find(x => x.label.Equals(preferredStartScrollName));
         if (preferredStartScroll != null)
             this.DetailScreen.GetComponent<ScrollDetails>().setScroll(preferredStartScroll);
     }
diff --git a/Assets/Scripts/InventoryStuff/ScrollDetails.cs b/Assets/Scripts/InventoryStuff/ScrollDetails.cs
index 355b6b1c20de5a3411b7df3e61a808d956b67075..2536c3004f3ad5adf2d1d75dfee5e906e5405eb9 100644
--- a/Assets/Scripts/InventoryStuff/ScrollDetails.cs
+++ b/Assets/Scripts/InventoryStuff/ScrollDetails.cs
@@ -10,7 +10,7 @@ public class ScrollDetails : MonoBehaviour
 {
     public WorldCursor cursor;
     public GameObject parameterDisplayPrefab;
-    public Scroll scroll;
+    public Scroll ActiveScroll;
 
     public int x_Start;
     public int y_Start;
@@ -44,7 +44,7 @@ public void setScroll(Scroll s)
         Transform originalScroll = gameObject.transform.GetChild(1).transform;
         Transform originalScrollView = originalScroll.GetChild(1);
         Transform originalViewport = originalScrollView.GetChild(0);
-        this.scroll = s;
+        this.ActiveScroll = s;
         originalScroll.GetChild(0).GetComponent<TextMeshProUGUI>().text = s.description;
 
         //Clear all current ScrollFacts
@@ -117,11 +117,7 @@ IEnumerator sendView(string endpoint)
         using UnityWebRequest www = UnityWebRequest.Put(ServerAdress + endpoint, body);
         www.method = UnityWebRequest.kHttpVerbPOST;
         www.SetRequestHeader("Content-Type", "application/json");
-        var async = www.SendWebRequest();
-        while (!async.isDone) {
-            //Non blocking wait for one frame, for letting the game do other things
-            yield return null;
-        }
+        yield return www.SendWebRequest();
 
         if (www.result == UnityWebRequest.Result.ConnectionError 
          || www.result == UnityWebRequest.Result.ProtocolError)
@@ -144,17 +140,19 @@ private string prepareScrollAssignments()
 
         for (int i = 0; i < ParameterDisplays.Count; i++)
         {
-            Scroll.ScrollAssignment listEntry = new Scroll.ScrollAssignment();
             tempFact = ParameterDisplays[i].GetComponentInChildren<DropHandling>().currentFact;
             if (tempFact != null)
             {
-                listEntry.fact = new Scroll.UriReference(this.scroll.requiredFacts[i].@ref.uri);
-                listEntry.assignment = new JSONManager.OMS(tempFact.Id);
+                Scroll.ScrollAssignment listEntry = new Scroll.ScrollAssignment
+                {
+                    fact = new Scroll.UriReference(ActiveScroll.requiredFacts[i].@ref.uri),
+                    assignment = new JSONManager.OMS(tempFact.Id)
+                };
                 assignmentList.Add(listEntry);
             }
         }
 
-        Scroll.FilledScroll filledScroll = new Scroll.FilledScroll(this.scroll.@ref, assignmentList);
+        Scroll.FilledScroll filledScroll = new Scroll.FilledScroll(ActiveScroll.@ref, assignmentList);
         return Scroll.ToJSON(filledScroll);
     }
 
@@ -169,7 +167,7 @@ private void readPushout(List<Scroll.ScrollFact> pushoutFacts)
             Fact newFact = ParsingDictionary.parseFactDictionary[pushoutFacts[i].getType()].Invoke(pushoutFacts[i]);
             if (newFact != null)
             {
-                PushoutFactEvent.Invoke(FactManager.AddFactIfNotFound(newFact, out bool exists, samestep));
+                PushoutFactEvent.Invoke(FactManager.AddFactIfNotFound(newFact, out bool exists, samestep, null, ActiveScroll.label));
             }
             else {
                 Debug.Log("Parsing on pushout-fact returned null -> One of the dependent facts does not exist");
diff --git a/Assets/Scripts/Loading/Stage.cs b/Assets/Scripts/Loading/Stage.cs
index a60aec46751ae23fe822307553689b8191ff45ab..04f8469c4b6ad3b0702b5e2546c742f1d923fe55 100644
--- a/Assets/Scripts/Loading/Stage.cs
+++ b/Assets/Scripts/Loading/Stage.cs
@@ -45,6 +45,8 @@ public class Stage: IJSONsavable<Stage>
     [JsonIgnore, JSONsavable.JsonSeparate]
     public SaveGame savegame = null;
 
+    //public List<PlayerRecord> solution_approches = new();
+
     #region makros/shortcuts
 
     /// <summary>