diff --git a/Assets/Scripts/GenerateDemoFiles.cs b/Assets/Scripts/GenerateDemoFiles.cs
index d335a60f3d7611f022e2f69fbf31db87abbeba8f..480ce3443edea2a11ae69c8c8c28ddce27786f3e 100644
--- a/Assets/Scripts/GenerateDemoFiles.cs
+++ b/Assets/Scripts/GenerateDemoFiles.cs
@@ -267,7 +267,7 @@ public static void GenerateCanonBallStage2D()
                         SOMDoc.MakeTupel(new OMLIT<float>[] { new((float)PythonParams[i].y1), new((float)PythonParams[i].y2) }),
                 });
         }
-        StageStatic.stage.solution.Add(
+        string RRRRURI = StageStatic.stage.solution.Add(
             new ListFact(null, RRRRTupel, null),
             out bool _, true, null, null
         );
@@ -292,6 +292,13 @@ public static void GenerateCanonBallStage2D()
         // Set Gadgets/ Scrolls
         StageStatic.stage.AllowedGadgets = null;
         StageStatic.stage.AllowedScrolls = new() { MMTConstants.ScrollCannonBall2D };
+        StageStatic.stage.solution.ScrollOverwrites.Add(MMTConstants.ScrollCannonBall2D, new[] {
+            (BallURI, 0, true),
+            (VecURI, 1, true),
+            (GravURI, 2, true),
+            (BounceURI, 3, true),
+            (RRRRURI, 4, true),
+        });
 
         // Save
         StageStatic.SetMode(StageStatic.Mode.Create);
@@ -481,7 +488,7 @@ public static void GenerateCanonBallStage3D()
 
         // Set Solution
         #region  CannonBallScroll
-        StageStatic.stage.solution.Add( // for CannonBallScroll
+        string TriangleURI = StageStatic.stage.solution.Add( // for CannonBallScroll
             new ListFact(Trieangles.Select(q => q.Id).ToArray(), null, new OMS(MMTConstants.TYPE_TO_OMS[typeof(TriangleFact)])),
             out bool _, true, null, null
         );
@@ -494,7 +501,7 @@ public static void GenerateCanonBallStage3D()
                 Walls[i].Pids.Select(p => new OMS(p)).ToArray()
             );
         }
-        StageStatic.stage.solution.Add(
+        string QuadURI = StageStatic.stage.solution.Add(
             new ListFact(null, RRRRTupel, null),
             out bool _, true, null, null
         );
@@ -524,6 +531,20 @@ public static void GenerateCanonBallStage3D()
         // Set Gadgets/ Scrolls
         StageStatic.stage.AllowedGadgets = null;
         StageStatic.stage.AllowedScrolls = new() { MMTConstants.ScrollCannonBall3D, MMTConstants.ScrollCannonBallT3D };
+        StageStatic.stage.solution.ScrollOverwrites.Add(MMTConstants.ScrollCannonBall3D, new[] {
+            (BallURI, 0, true),
+            (VecURI, 1, true),
+            (GravURI, 2, true),
+            (BounceURI, 3, true),
+            (QuadURI, 4, true),
+        });
+        StageStatic.stage.solution.ScrollOverwrites.Add(MMTConstants.ScrollCannonBallT3D, new[] {
+            (BallURI, 0, true),
+            (VecURI, 1, true),
+            (GravURI, 2, true),
+            (BounceURI, 3, true),
+            (TriangleURI, 4, true),
+        });
 
         // Save
         StageStatic.SetMode(StageStatic.Mode.Create);
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs
index 698b1fe3ea6799d60f9d9896c0e8ce215738380e..18c845a7db53ea5605cf1a0a2fdfd82fd3eb4529 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs
@@ -646,7 +646,9 @@ protected bool DependentFactsEquivalent(T f1, T f2)
             .Zip(f2.DependentFactIds,
                 (id1, id2) =>
                     id1 == id2
-                    || FactRecorder.AllFacts[id1].Equivalent(FactRecorder.AllFacts[id2])
+                    || (FactRecorder.AllFacts.ContainsKey(id1)
+                     && FactRecorder.AllFacts.ContainsKey(id2)
+                     && FactRecorder.AllFacts[id1].Equivalent(FactRecorder.AllFacts[id2]))
             )
             .All(b => b);
 }
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/MMTTypes.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/MMTTypes.cs
index 5042da9c85b0180960d17963a9d12aff1d932f86..6fcd8fc5a3ed0dc4a0230f595c44ac018beb40dd 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/MMTTypes.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/MMTTypes.cs
@@ -403,9 +403,9 @@ public class DynamicTupleFact : FactWrappedCRTP<DynamicTupleFact>, IUnpackable
     protected override object GetCompiledValue() => payload;
 
     [JsonIgnore]
-    object payload;
+    object payload = null;
 
-    int count;
+    int count = 0;
 
     [JsonIgnore]
     public Type[] Signature => _Signature ??= payload.GetType().GetGenericArguments();
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/SolutionRecorder.cs b/Assets/Scripts/InteractionEngine/FactHandling/SolutionRecorder.cs
index f7c3b896c8dc5ae7fc861325a19b6019b66642c5..f340a9fe2fb2c2b48fe7152bbd75ca3363f60386 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/SolutionRecorder.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/SolutionRecorder.cs
@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Reflection;
+using MoreLinq;
 using Newtonsoft.Json;
 using static CommunicationEvents;
 
@@ -24,11 +25,12 @@ private const string
     /// </summary>
     public List<SubSolution> ValidationSet = new();
 
-    /// <summary>
-    /// Contains <see cref="Fact.Id"/>s which are being exposed to the Player
-    /// </summary>
+    /// <summary> Contains <see cref="Fact.Id"/>s which are being exposed to the Player </summary>
     public List<string> ExposedSolutionFacts = new();
 
+    /// <summary> Maps <see cref="REST_JSON_API.Scroll.ScrollReference"/>s to settings to apply to itself. </summary>
+    public Dictionary<string, (string Id, int index, bool show)[]> ScrollOverwrites = new();
+
     /// <summary>
     /// Sits at the heart, but represents only a part of the whole Solution.
     /// </summary>
@@ -159,6 +161,12 @@ SolutionRecorder IJSONsavable<SolutionRecorder>._IJPostProcess(SolutionRecorder
             .Select(fid => old_to_new[fid])
             .ToList();
 
+        payload.ScrollOverwrites = raw_payload.ScrollOverwrites
+            .Select(kv => new KeyValuePair<string, (string Id, int index, bool show)[]>(
+                kv.Key,
+                kv.Value.Select(t => (old_to_new[t.Id], t.index, t.show)).ToArray())
+            ).ToDictionary();
+
         return payload;
     }
 
diff --git a/Assets/Scripts/InventoryStuff/ScrollDetails.cs b/Assets/Scripts/InventoryStuff/ScrollDetails.cs
index b5651ac5b32a4fbbc744c990637cb4c9d40c5733..6c570edb9e9e9aa14d5c714eba699a778b9ecee4 100644
--- a/Assets/Scripts/InventoryStuff/ScrollDetails.cs
+++ b/Assets/Scripts/InventoryStuff/ScrollDetails.cs
@@ -43,7 +43,8 @@ public static ScrollDetails Instance
     private bool DynamicScrollInQue = false;
     private bool MagicInQue = false;
 
-    private readonly IReadOnlyList<string> NoDynamicScroll = new List<string>() {
+    private readonly IReadOnlyList<string> NoDynamicScroll = new List<string>()
+    {
         // Insert ScrollURIS that are poorly optimized
     };
 
@@ -107,6 +108,15 @@ public void SetScroll(Scroll scroll_to_set)
             originalRSF.Populate(ActiveScroll, i);
         }
 
+        if (StageStatic.stage.solution.ScrollOverwrites
+            .TryGetValue(ActiveScroll.ScrollReference, out (string, int, bool)[] population)
+        )
+            foreach ((string Id, int index, bool show) in population)
+            {
+                ParameterDisplays[index].URI = Id;
+                ParameterDisplays[index].transform.parent.gameObject.SetActive(show);
+            }
+
         foreach (int i in PrePopulateActiveScroll())
             ParameterDisplays[i].transform.parent.gameObject.SetActive(false);
     }
@@ -116,8 +126,7 @@ public bool SetNextEmptyTo(FactObjectUI activator)
         RenderedScrollFact check = ParameterDisplays
             .Find(RSF => RSF != null
                       && RSF.Payload != null
-                      && RSF.Payload.Equals(activator)
-        );
+                      && RSF.Payload.Equals(activator));
 
         if (check != null)
         {
diff --git a/Assets/Scripts/Loading/Stage.cs b/Assets/Scripts/Loading/Stage.cs
index 794595444f41e4452899395690dddaf91590c48e..da0090ba911f87447cd37d90030432d30fc46e29 100644
--- a/Assets/Scripts/Loading/Stage.cs
+++ b/Assets/Scripts/Loading/Stage.cs
@@ -49,10 +49,15 @@ public class Stage : IJSONsavable<Stage>
     [JsonIgnore, JSONsavable.JsonSeparate]
     public SaveGame savegame = null;
 
+    [JsonProperty] // unused, but could be for resuming
+    private string record_index;
+
     public List<PlayerRecord> solution_approches = new();
     public List<string> AllowedScrolls = null;
     public List<Gadget> AllowedGadgets = null;
 
+    //TODO: auto fill for scrolls, take from solution
+
     #region makros/shortcuts
 
     /// <summary>
@@ -73,8 +78,6 @@ public PlayerRecord player_record
             value.CopyExposedSolutionFacts(this);
         }
     }
-    [JsonProperty] // unused, but could be for resuming
-    private string record_index;
 
     /// <summary>
     /// A list containing all saved player progress. <br/>
diff --git a/Assets/Scripts/StageBehaviour.cs b/Assets/Scripts/StageBehaviour.cs
index 18186009f4f5eabc70150c8259dd880196d34296..d9b4a6b022735b36390fda4e3c000d89bf879944 100644
--- a/Assets/Scripts/StageBehaviour.cs
+++ b/Assets/Scripts/StageBehaviour.cs
@@ -27,6 +27,9 @@ public static List<TriangleFact> GenerateMMTCollider(GameObject obj = null)
 
         foreach (BoxCollider coll in FindObjectsOfType<BoxCollider>())
         {
+            if(!UseMe(coll))
+                continue;
+
             Vector3[] minmax = new Vector3[]
             {
                 coll.center - coll.size/2,
@@ -60,7 +63,8 @@ void _TrisAdd(uint i, uint j, uint k)
 
         //foreach (MeshCollider coll in FindObjectsOfType<MeshCollider>())
         //{
-        //    if (!coll.sharedMesh.isReadable)
+        //    if (!UseMe(coll)
+        //     || !coll.sharedMesh.isReadable)
         //        continue;
 
         //    for (int i = 0; i < coll.sharedMesh.triangles.Length; i += 3)
@@ -100,6 +104,8 @@ Vector3 _Transform(Vector3 vert, Matrix4x4 toworld)
             Vector4 h = toworld * new Vector4(vert.x, vert.y, vert.z, 1f);
             return new Vector3(h.x, h.y, h.z);
         }
+
+        bool UseMe(Collider coll) => true; //TODO: filter for what we want
     }
 
     /// <summary>