diff --git a/BenchmarkTest/BenchmarkTest.csproj b/BenchmarkTest/BenchmarkTest.csproj
new file mode 100644
index 0000000..f569f93
--- /dev/null
+++ b/BenchmarkTest/BenchmarkTest.csproj
@@ -0,0 +1,18 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BenchmarkTest/DecompileBenchmark.cs b/BenchmarkTest/DecompileBenchmark.cs
new file mode 100644
index 0000000..e83979f
--- /dev/null
+++ b/BenchmarkTest/DecompileBenchmark.cs
@@ -0,0 +1,41 @@
+using BenchmarkDotNet.Attributes;
+using UndertaleModLib;
+using UndertaleModLib.Decompiler;
+using UndertaleModLib.Models;
+
+namespace BenchmarkTest;
+
+[MemoryDiagnoser]
+public class DecompileBenchmark
+{
+ public UndertaleData data;
+ public GlobalDecompileContext decompileContext;
+
+ [GlobalSetup]
+ public void GlobalSetup()
+ {
+ using (FileStream fs = new FileInfo(@"/home/narr/Dokumente/am2r 1.5.5/assets/game.unx_older").OpenRead())
+ {
+ data = UndertaleIO.Read(fs);
+ }
+ decompileContext = new GlobalDecompileContext(data, false);
+ }
+
+ [Benchmark]
+ public void AppendVariableToEveryEntry()
+ {
+ void AppendGML(UndertaleCode code, string appendedText)
+ {
+ var codeText = Decompiler.Decompile(code, decompileContext);
+ codeText = codeText + appendedText + "\n";
+ code.ReplaceGML(codeText, data);
+ }
+
+ foreach (UndertaleCode codeentry in data.Code.SkipLast((int)(data.Code.Count * 0.99)))
+ {
+ if (codeentry.Name.Content == "gml_Object_oRm_a5c11lock_Collision_267") continue;
+
+ AppendGML(codeentry, "var this_variable_is_not_used_and_thus_completely_uselesss = 1; if (!this_variable_is_not_used_and_thus_completely_uselesss) this_variable_is_not_used_and_thus_completely_uselesss = 1");
+ }
+ }
+}
diff --git a/BenchmarkTest/Program.cs b/BenchmarkTest/Program.cs
new file mode 100644
index 0000000..334df3d
--- /dev/null
+++ b/BenchmarkTest/Program.cs
@@ -0,0 +1,7 @@
+// See https://aka.ms/new-console-template for more information
+
+using BenchmarkDotNet.Running;
+using BenchmarkTest;
+
+Console.WriteLine("Hello, World!");
+BenchmarkRunner.Run();
diff --git a/YAMS-LIB/patches/DecoupleItemsFromLocations.cs b/YAMS-LIB/patches/DecoupleItemsFromLocations.cs
index 4b8d386..b2ff875 100644
--- a/YAMS-LIB/patches/DecoupleItemsFromLocations.cs
+++ b/YAMS-LIB/patches/DecoupleItemsFromLocations.cs
@@ -38,31 +38,31 @@ public static void Apply(UndertaleData gmData, GlobalDecompileContext decompileC
gmData.Code.ByName(code).ReplaceGMLInCode("global.item[0]", "global.hasBombs");
}
- UndertaleGameObject? elderSeptogg = gmData.GameObjects.ByName("oElderSeptogg");
+ const string elderSeptoggName = "oElderSeptogg";
foreach (var gameObject in new[]
{
- gmData.Rooms.ByName("rm_a0h11").GameObjects.First(go => go.X == 480 && go.Y == 768 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a0h25").GameObjects.First(go => go.X == 120 && go.Y == 816 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a0h25").GameObjects.First(go => go.X == 168 && go.Y == 256 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a0h29").GameObjects.First(go => go.X == 384 && go.Y == 312 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a1h05").GameObjects.First(go => go.X == 1184 && go.Y == 832 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a3h04").GameObjects.First(go => go.X == 528 && go.Y == 1344 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a3h04").GameObjects.First(go => go.X == 1728 && go.Y == 1248 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a3a07").GameObjects.First(go => go.X == 112 && go.Y == 240 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a3b02").GameObjects.First(go => go.X == 192 && go.Y == 896 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a3b08").GameObjects.First(go => go.X == 224 && go.Y == 352 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a0h17").GameObjects.First(go => go.X == 96 && go.Y == 352 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a4b02a").GameObjects.First(go => go.X == 120 && go.Y == 816 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a4b10").GameObjects.First(go => go.X == 144 && go.Y == 624 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a4b10").GameObjects.First(go => go.X == 512 && go.Y == 256 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a4b11").GameObjects.First(go => go.X == 224 && go.Y == 2288 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a5c13").GameObjects.First(go => go.X == 96 && go.Y == 704 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a5c14").GameObjects.First(go => go.X == 1056 && go.Y == 288 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a5c17").GameObjects.First(go => go.X == 192 && go.Y == 288 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a5c18").GameObjects.First(go => go.X == 128 && go.Y == 192 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a5c18").GameObjects.First(go => go.X == 480 && go.Y == 192 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a5c21").GameObjects.First(go => go.X == 160 && go.Y == 384 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
- gmData.Rooms.ByName("rm_a5c21").GameObjects.First(go => go.X == 96 && go.Y == 560 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content),
+ gmData.Rooms.ByName("rm_a0h11").GameObjects.First(go => go.X == 480 && go.Y == 768 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a0h25").GameObjects.First(go => go.X == 120 && go.Y == 816 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a0h25").GameObjects.First(go => go.X == 168 && go.Y == 256 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a0h29").GameObjects.First(go => go.X == 384 && go.Y == 312 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a1h05").GameObjects.First(go => go.X == 1184 && go.Y == 832 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a3h04").GameObjects.First(go => go.X == 528 && go.Y == 1344 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a3h04").GameObjects.First(go => go.X == 1728 && go.Y == 1248 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a3a07").GameObjects.First(go => go.X == 112 && go.Y == 240 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a3b02").GameObjects.First(go => go.X == 192 && go.Y == 896 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a3b08").GameObjects.First(go => go.X == 224 && go.Y == 352 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a0h17").GameObjects.First(go => go.X == 96 && go.Y == 352 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a4b02a").GameObjects.First(go => go.X == 120 && go.Y == 816 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a4b10").GameObjects.First(go => go.X == 144 && go.Y == 624 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a4b10").GameObjects.First(go => go.X == 512 && go.Y == 256 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a4b11").GameObjects.First(go => go.X == 224 && go.Y == 2288 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a5c13").GameObjects.First(go => go.X == 96 && go.Y == 704 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a5c14").GameObjects.First(go => go.X == 1056 && go.Y == 288 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a5c17").GameObjects.First(go => go.X == 192 && go.Y == 288 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a5c18").GameObjects.First(go => go.X == 128 && go.Y == 192 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a5c18").GameObjects.First(go => go.X == 480 && go.Y == 192 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a5c21").GameObjects.First(go => go.X == 160 && go.Y == 384 && go.ObjectDefinition.Name.Content == elderSeptoggName),
+ gmData.Rooms.ByName("rm_a5c21").GameObjects.First(go => go.X == 96 && go.Y == 560 && go.ObjectDefinition.Name.Content == elderSeptoggName),
})
{
gameObject.CreationCode.ReplaceGMLInCode("global.item[0]", "global.hasBombs");
@@ -77,7 +77,7 @@ public static void Apply(UndertaleData gmData, GlobalDecompileContext decompileC
subscreenMenuStep.ReplaceGMLInCode("global.item[2] == 0", "!global.hasSpiderball");
foreach (UndertaleCode code in gmData.Code.Where(c =>
(c.Name.Content.StartsWith("gml_Script_scr_septoggs_") && c.Name.Content.Contains('2')) ||
- c.Name.Content == gmData.Rooms.ByName("rm_a0h25").GameObjects.First(go => go.X == 120 && go.Y == 816 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content).CreationCode.Name.Content)
+ c.Name.Content == gmData.Rooms.ByName("rm_a0h25").GameObjects.First(go => go.X == 120 && go.Y == 816 && go.ObjectDefinition.Name.Content == elderSeptoggName).CreationCode.Name.Content)
)
{
code.ReplaceGMLInCode("global.item[2]", "global.hasSpiderball");
@@ -95,7 +95,7 @@ public static void Apply(UndertaleData gmData, GlobalDecompileContext decompileC
foreach (UndertaleCode? code in gmData.Code.Where(c =>
(c.Name.Content.StartsWith("gml_Script_scr_septoggs_") && c.Name.Content.Contains('4')) ||
c.Name.Content == "gml_Room_rm_a3b08_Create" ||
- c == gmData.Rooms.ByName("rm_a5c17").GameObjects.First(go => go.X == 192 && go.Y == 288 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content).CreationCode)
+ c == gmData.Rooms.ByName("rm_a5c17").GameObjects.First(go => go.X == 192 && go.Y == 288 && go.ObjectDefinition.Name.Content == elderSeptoggName).CreationCode)
)
{
code.ReplaceGMLInCode("global.item[4]", "global.hasHijump");
@@ -120,7 +120,7 @@ public static void Apply(UndertaleData gmData, GlobalDecompileContext decompileC
foreach (UndertaleCode? code in gmData.Code.Where(c =>
(c.Name.Content.StartsWith("gml_Script_scr_septoggs_") && c.Name.Content.Contains('6')) ||
gmData.Rooms.ByName("rm_a5a03").GameObjects.Where(go => go.X is >= 96 and <= 112 && go.Y is >= 240 and <= 288 && go.ObjectDefinition.Name.Content == "oBlockStep").Select(go => go.CreationCode).Contains(c) ||
- c == gmData.Rooms.ByName("rm_a0h25").GameObjects.First(go => go.X == 120 && go.Y == 816 && go.ObjectDefinition.Name.Content == elderSeptogg.Name.Content).CreationCode)
+ c == gmData.Rooms.ByName("rm_a0h25").GameObjects.First(go => go.X == 120 && go.Y == 816 && go.ObjectDefinition.Name.Content == elderSeptoggName).CreationCode)
)
{
code.ReplaceGMLInCode("global.item[6]", "global.hasSpacejump");
diff --git a/diff.txt b/diff.txt
new file mode 100644
index 0000000..1a17044
--- /dev/null
+++ b/diff.txt
@@ -0,0 +1,40 @@
+diff --git a/UndertaleModLib/Compiler/Compiler.cs b/UndertaleModLib/Compiler/Compiler.cs
+index 3fa2ae6b..72e3d7c9 100644
+--- a/UndertaleModLib/Compiler/Compiler.cs
++++ b/UndertaleModLib/Compiler/Compiler.cs
+@@ -142,8 +142,11 @@ namespace UndertaleModLib.Compiler
+ for (int i = 0; i < list.Count; i++)
+ {
+ string name = list[i].Name?.Content;
+- if (name != null)
+- assetIds[name] = i;
++ if (name is not null)
++ {
++ assetIds.Add(name, i);
++ }
++ //assetIds[name] = i;
+ }
+ }
+ }
+@@ -154,6 +157,8 @@ namespace UndertaleModLib.Compiler
+ public delegate void MainThreadFunc();
+ public delegate void MainThreadDelegate(MainThreadFunc f);
+
++ private static Dictionary codeToContextMapping = new Dictionary();
++
+ // A simple matching convenience
+ public static bool In(this T obj, params T[] args)
+ {
+@@ -169,7 +174,11 @@ namespace UndertaleModLib.Compiler
+
+ public static CompileContext CompileGMLText(string input, UndertaleData data, UndertaleCode code)
+ {
+- return CompileGMLText(input, new CompileContext(data, code));
++ bool isInMapping = codeToContextMapping.TryGetValue(data, out CompileContext ctx);
++ var returnedContext = CompileGMLText(input, ctx ?? new CompileContext(data, code));
++ if (!isInMapping)
++ codeToContextMapping.Add(data, returnedContext);
++ return returnedContext;
+ }
+
+ public static CompileContext CompileGMLText(string input, CompileContext context, bool redoAssets = false)