From 508d4f776a9a765a56720fc350ccb347515e3897 Mon Sep 17 00:00:00 2001
From: tharbad08 <10381553+tharbad08@users.noreply.github.com>
Date: Sat, 17 Oct 2026 07:05:13 +0300
Subject: [PATCH] Port Benchmark & Optimizer profiling to Timberborn 1.1
Restore on-demand 120-second CSV and frame/GC profiling, protected per-system update intervals, optional TimberPhysics timing, and the pause-menu settings shortcut. Port 1.1.104 is validated in game by tester and remains independent of stable TB Optimizer. Build and packaging workflow included; original U7 mod remains untouched.
---
.github/workflows/build-benchmark-v11port.yml | 39 +
.../BenchmarkAndOptimizerV11Port.csproj | 33 +
.../DispatcherPatcher.cs | 83 +
.../FrameProfileSampler.cs | 76 +
.../IsExternalInit.cs | 6 +
BenchmarkAndOptimizerV11Port/ModStarter.cs | 20 +
BenchmarkAndOptimizerV11Port/README.md | 49 +
BenchmarkAndOptimizerV11Port/Runtime.cs | 1416 +++++++++++++++++
.../SettingsIntegration.cs | 556 +++++++
.../Bindito.Core/Bindito.Core.Stub.csproj | 3 +
.../Stubs/Bindito.Core/Stub.cs | 16 +
.../ModSettings.CommonUI.Stub.csproj | 14 +
.../Stubs/ModSettings.CommonUI/Stub.cs | 11 +
.../ModSettings.Core.Stub.csproj | 13 +
.../Stubs/ModSettings.Core/Stub.cs | 27 +
.../ModSettings.CoreUI.Stub.csproj | 13 +
.../Stubs/ModSettings.CoreUI/Stub.cs | 13 +
.../Stubs/TimberUi/Stub.cs | 56 +
.../Stubs/TimberUi/TimberUi.Stub.csproj | 1 +
.../Stubs/Timberborn.CoreUI/Stub.cs | 11 +
.../Timberborn.CoreUI.Stub.csproj | 12 +
.../Stubs/Timberborn.ModManagerScene/Stub.cs | 12 +
.../Timberborn.ModManagerScene.Stub.csproj | 9 +
.../Stubs/Timberborn.Modding/Stub.cs | 5 +
.../Timberborn.Modding.Stub.csproj | 9 +
.../Stubs/Timberborn.Options/Stub.cs | 4 +
.../Timberborn.Options.Stub.csproj | 9 +
.../Stubs/Timberborn.OptionsGame/Stub.cs | 9 +
.../Timberborn.OptionsGame.Stub.csproj | 13 +
.../Stubs/Timberborn.SettingsSystem/Stub.cs | 1 +
.../Timberborn.SettingsSystem.Stub.csproj | 9 +
.../Stubs/Timberborn.SingletonSystem/Stub.cs | 22 +
.../Timberborn.SingletonSystem.Stub.csproj | 9 +
.../UnityEngine.UIElementsModule/Stub.cs | 110 ++
.../UnityEngine.UIElementsModule.Stub.csproj | 9 +
BenchmarkAndOptimizerV11Port/TICK_SAFETY.md | 15 +
.../TimberPhysicsBenchmarkPatcher.cs | 159 ++
BenchmarkAndOptimizerV11Port/manifest.json | 25 +
38 files changed, 2897 insertions(+)
create mode 100644 .github/workflows/build-benchmark-v11port.yml
create mode 100644 BenchmarkAndOptimizerV11Port/BenchmarkAndOptimizerV11Port.csproj
create mode 100644 BenchmarkAndOptimizerV11Port/DispatcherPatcher.cs
create mode 100644 BenchmarkAndOptimizerV11Port/FrameProfileSampler.cs
create mode 100644 BenchmarkAndOptimizerV11Port/IsExternalInit.cs
create mode 100644 BenchmarkAndOptimizerV11Port/ModStarter.cs
create mode 100644 BenchmarkAndOptimizerV11Port/README.md
create mode 100644 BenchmarkAndOptimizerV11Port/Runtime.cs
create mode 100644 BenchmarkAndOptimizerV11Port/SettingsIntegration.cs
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/Bindito.Core/Bindito.Core.Stub.csproj
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/Bindito.Core/Stub.cs
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/ModSettings.CommonUI/ModSettings.CommonUI.Stub.csproj
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/ModSettings.CommonUI/Stub.cs
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/ModSettings.Core/ModSettings.Core.Stub.csproj
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/ModSettings.Core/Stub.cs
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/ModSettings.CoreUI/ModSettings.CoreUI.Stub.csproj
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/ModSettings.CoreUI/Stub.cs
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/TimberUi/Stub.cs
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/TimberUi/TimberUi.Stub.csproj
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/Timberborn.CoreUI/Stub.cs
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/Timberborn.CoreUI/Timberborn.CoreUI.Stub.csproj
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/Timberborn.ModManagerScene/Stub.cs
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/Timberborn.ModManagerScene/Timberborn.ModManagerScene.Stub.csproj
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/Timberborn.Modding/Stub.cs
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/Timberborn.Modding/Timberborn.Modding.Stub.csproj
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/Timberborn.Options/Stub.cs
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/Timberborn.Options/Timberborn.Options.Stub.csproj
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/Timberborn.OptionsGame/Stub.cs
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/Timberborn.OptionsGame/Timberborn.OptionsGame.Stub.csproj
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/Timberborn.SettingsSystem/Stub.cs
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/Timberborn.SettingsSystem/Timberborn.SettingsSystem.Stub.csproj
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/Timberborn.SingletonSystem/Stub.cs
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/Timberborn.SingletonSystem/Timberborn.SingletonSystem.Stub.csproj
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/UnityEngine.UIElementsModule/Stub.cs
create mode 100644 BenchmarkAndOptimizerV11Port/Stubs/UnityEngine.UIElementsModule/UnityEngine.UIElementsModule.Stub.csproj
create mode 100644 BenchmarkAndOptimizerV11Port/TICK_SAFETY.md
create mode 100644 BenchmarkAndOptimizerV11Port/TimberPhysicsBenchmarkPatcher.cs
create mode 100644 BenchmarkAndOptimizerV11Port/manifest.json
diff --git a/.github/workflows/build-benchmark-v11port.yml b/.github/workflows/build-benchmark-v11port.yml
new file mode 100644
index 00000000..498379c7
--- /dev/null
+++ b/.github/workflows/build-benchmark-v11port.yml
@@ -0,0 +1,39 @@
+name: Build BenchmarkAndOptimizerV11Port
+on:
+ push:
+ branches:
+ - pr/benchmark-optimizer-v11-clean
+ paths:
+ - 'BenchmarkAndOptimizerV11Port/**'
+ - '.github/workflows/build-benchmark-v11port.yml'
+ pull_request:
+ paths:
+ - 'BenchmarkAndOptimizerV11Port/**'
+ - '.github/workflows/build-benchmark-v11port.yml'
+ workflow_dispatch:
+permissions:
+ contents: read
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: '8.0.x'
+ - name: Build CSV profiler
+ run: dotnet build BenchmarkAndOptimizerV11Port/BenchmarkAndOptimizerV11Port.csproj -c Release
+ - name: Stage ready-to-install mod
+ shell: bash
+ run: |
+ set -euxo pipefail
+ ROOT="${RUNNER_TEMP}/timberborn-artifact/BenchmarkAndOptimizerV11Port"
+ mkdir -p "$ROOT/version-1.1/Scripts"
+ cp BenchmarkAndOptimizerV11Port/manifest.json "$ROOT/version-1.1/manifest.json"
+ cp BenchmarkAndOptimizerV11Port/bin/Release/netstandard2.1/BenchmarkAndOptimizerV11.dll "$ROOT/version-1.1/Scripts/"
+ test -s "$ROOT/version-1.1/Scripts/BenchmarkAndOptimizerV11.dll"
+ - uses: actions/upload-artifact@v4
+ with:
+ name: BenchmarkAndOptimizerV11Port_1.1.104
+ path: ${{ runner.temp }}/timberborn-artifact/
+ if-no-files-found: error
diff --git a/BenchmarkAndOptimizerV11Port/BenchmarkAndOptimizerV11Port.csproj b/BenchmarkAndOptimizerV11Port/BenchmarkAndOptimizerV11Port.csproj
new file mode 100644
index 00000000..3a7bca00
--- /dev/null
+++ b/BenchmarkAndOptimizerV11Port/BenchmarkAndOptimizerV11Port.csproj
@@ -0,0 +1,33 @@
+
+
+ netstandard2.1
+ latest
+ enable
+ enable
+ BenchmarkAndOptimizerV11
+ BenchmarkAndOptimizerV11
+ 1.1.104.0
+ 1.1.104.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BenchmarkAndOptimizerV11Port/DispatcherPatcher.cs b/BenchmarkAndOptimizerV11Port/DispatcherPatcher.cs
new file mode 100644
index 00000000..439bd836
--- /dev/null
+++ b/BenchmarkAndOptimizerV11Port/DispatcherPatcher.cs
@@ -0,0 +1,83 @@
+using System.Collections;
+using System.Reflection;
+using System.Linq.Expressions;
+using System.Runtime.CompilerServices;
+using Newtonsoft.Json;
+using HarmonyLib;
+using Timberborn.ModManagerScene;
+
+namespace BenchmarkAndOptimizerV11;
+
+static class DispatcherPatcher
+{
+ static bool isPatched;
+
+ readonly record struct Target(string TypeName, string MethodName, string PrefixName);
+
+ static readonly Target[] Targets =
+ {
+ new("Timberborn.TickSystem.TickableSingletonService", "TickSingletons", nameof(PrefixTickSingletons)),
+ new("Timberborn.TickSystem.TickableEntity", "TickTickableComponents", nameof(PrefixTickableComponents)),
+ new("Timberborn.SingletonSystem.SingletonLifecycleService", "UpdateSingletons", nameof(PrefixUpdateSingletons)),
+ new("Timberborn.SingletonSystem.SingletonLifecycleService", "LateUpdateSingletons", nameof(PrefixLateUpdateSingletons)),
+ };
+
+ public static void Patch(Harmony harmony)
+ {
+ if (isPatched)
+ {
+ return;
+ }
+
+ foreach (var target in Targets)
+ {
+ var type = AccessTools.TypeByName(target.TypeName);
+ var original = type is null ? null : AccessTools.Method(type, target.MethodName);
+ var prefix = AccessTools.Method(typeof(DispatcherPatcher), target.PrefixName);
+
+ if (original is null || prefix is null)
+ {
+ Runtime.Log($"warning: target not found: {target.TypeName}.{target.MethodName}; leaving vanilla behavior");
+ continue;
+ }
+
+ harmony.Patch(original, prefix: new HarmonyMethod(prefix) { priority = Priority.Low });
+ Runtime.Log($"benchmark patch installed: {target.TypeName}.{target.MethodName}");
+ }
+
+ isPatched = true;
+ }
+
+ public static void Unpatch(Harmony harmony)
+ {
+ if (!isPatched)
+ {
+ return;
+ }
+
+ foreach (var target in Targets)
+ {
+ var type = AccessTools.TypeByName(target.TypeName);
+ var original = type is null ? null : AccessTools.Method(type, target.MethodName);
+ if (original is not null)
+ {
+ harmony.Unpatch(original, HarmonyPatchType.Prefix, harmony.Id);
+ }
+ }
+
+ isPatched = false;
+ Runtime.Log("benchmark dispatcher patches removed");
+ }
+
+ public static bool PrefixTickSingletons(object __instance) =>
+ Runtime.TryDispatch(__instance, "_tickableSingletons", "_tickableSingleton", "Tick");
+
+ public static bool PrefixTickableComponents(object __instance) =>
+ Runtime.TryDispatch(__instance, "_tickableComponents", "_tickableComponent", "StartAndTick", "Enabled");
+
+ public static bool PrefixUpdateSingletons(object __instance) =>
+ Runtime.TryDispatch(__instance, "_updatableSingletons", null, "UpdateSingleton");
+
+ public static bool PrefixLateUpdateSingletons(object __instance) =>
+ Runtime.TryDispatch(__instance, "_lateUpdatableSingletons", null, "LateUpdateSingleton");
+}
diff --git a/BenchmarkAndOptimizerV11Port/FrameProfileSampler.cs b/BenchmarkAndOptimizerV11Port/FrameProfileSampler.cs
new file mode 100644
index 00000000..a6e87e70
--- /dev/null
+++ b/BenchmarkAndOptimizerV11Port/FrameProfileSampler.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+using HarmonyLib;
+
+namespace BenchmarkAndOptimizerV11;
+
+///
+/// Optional, read-only frame/GC samples during the existing 120s CSV benchmark.
+/// Records one row per ten Unity UpdateSingletons calls, and never skips game logic.
+/// This does not turn on legacy scene-wide, mod-specific or invasive profilers.
+///
+static class FrameProfileSampler
+{
+ static MethodBase? targetMethod;
+ static bool isPatched;
+ static long startTick;
+ static long sampleTick;
+ static int frames;
+ static int lastSampleFrame;
+ static readonly List Rows = [];
+
+ public static void Patch(Harmony harmony)
+ {
+ if (isPatched) { return; }
+ var lifecycle = AccessTools.TypeByName("Timberborn.SingletonSystem.SingletonLifecycleService");
+ targetMethod = lifecycle is null ? null : AccessTools.Method(lifecycle, "UpdateSingletons");
+ if (targetMethod is null) { return; }
+ try
+ {
+ harmony.Patch(targetMethod, postfix: new HarmonyMethod(AccessTools.Method(typeof(FrameProfileSampler), nameof(AfterUpdate))));
+ Rows.Clear();
+ Rows.Add("Frame,ElapsedSeconds,FrameMsAvg,FPS,GC0,GC1,GC2,ManagedHeapBytes");
+ startTick = sampleTick = Stopwatch.GetTimestamp();
+ frames = lastSampleFrame = 0;
+ isPatched = true;
+ }
+ catch { targetMethod = null; isPatched = false; }
+ }
+
+ static void AfterUpdate()
+ {
+ if (!isPatched || !Runtime.IsBenchmarking) { return; }
+ ++frames;
+ if (frames - lastSampleFrame < 10) { return; }
+ var now = Stopwatch.GetTimestamp();
+ var n = frames - lastSampleFrame;
+ var seconds = (now - sampleTick) / (double)Stopwatch.Frequency;
+ if (seconds <= 0) { return; }
+ Rows.Add(FormattableString.Invariant(
+ $"{frames},{(now - startTick) / (double)Stopwatch.Frequency:F3},{1000 * seconds / n:F3},{n / seconds:F2},{GC.CollectionCount(0)},{GC.CollectionCount(1)},{GC.CollectionCount(2)},{GC.GetTotalMemory(false)}"));
+ sampleTick = now;
+ lastSampleFrame = frames;
+ }
+
+ public static void StopAndWrite(Harmony? harmony, string modPath)
+ {
+ if (!isPatched) { return; }
+ isPatched = false;
+ if (harmony is not null && targetMethod is not null)
+ {
+ try { harmony.Unpatch(targetMethod, HarmonyPatchType.Postfix, harmony.Id); }
+ catch { /* Never alter the caller's benchmark completion. */ }
+ }
+ targetMethod = null;
+ try
+ {
+ File.WriteAllLines(Path.Combine(modPath,
+ $"optimizer-v11-frames-{DateTime.Now:yyyyMMdd-HHmmss}.csv"), Rows);
+ }
+ catch { /* CSV profiling failure must not break gameplay. */ }
+ Rows.Clear();
+ }
+}
diff --git a/BenchmarkAndOptimizerV11Port/IsExternalInit.cs b/BenchmarkAndOptimizerV11Port/IsExternalInit.cs
new file mode 100644
index 00000000..2632f761
--- /dev/null
+++ b/BenchmarkAndOptimizerV11Port/IsExternalInit.cs
@@ -0,0 +1,6 @@
+namespace System.Runtime.CompilerServices
+{
+ internal static class IsExternalInit
+ {
+ }
+}
diff --git a/BenchmarkAndOptimizerV11Port/ModStarter.cs b/BenchmarkAndOptimizerV11Port/ModStarter.cs
new file mode 100644
index 00000000..d2277720
--- /dev/null
+++ b/BenchmarkAndOptimizerV11Port/ModStarter.cs
@@ -0,0 +1,20 @@
+using System.Collections;
+using System.Reflection;
+using System.Linq.Expressions;
+using System.Runtime.CompilerServices;
+using Newtonsoft.Json;
+using HarmonyLib;
+using Timberborn.ModManagerScene;
+
+namespace BenchmarkAndOptimizerV11;
+
+public sealed class ModStarter : IModStarter
+{
+ public void StartMod(IModEnvironment modEnvironment)
+ {
+ var harmony = new Harmony("tharbad08.BenchmarkAndOptimizerV11Port");
+ Runtime.Initialize(modEnvironment.ModPath, harmony);
+
+ Runtime.Log($"loaded; config={Runtime.ConfigPath}; normal throttling uses direct method patches");
+ }
+}
diff --git a/BenchmarkAndOptimizerV11Port/README.md b/BenchmarkAndOptimizerV11Port/README.md
new file mode 100644
index 00000000..cbe95ce1
--- /dev/null
+++ b/BenchmarkAndOptimizerV11Port/README.md
@@ -0,0 +1,49 @@
+# Benchmark & Optimizer — isolated Timberborn v1.1 port
+
+This branch is based on `chatgpt/BenchmarkAndOptimizerV11Port`. It retains only the original benchmark/CSV profiler and opt-in interval controls. It is **not** the TB Optimizer gameplay mod.
+
+- **Per-system CSV benchmark:** start the 120-second sampling session from Mod Settings. Results `optimizer-v11-benchmark-*.csv` contain type, mod origin, total time, invocation count, average/min/max duration. TimberPhysics has observational StepAll/Physics.Simulate timing when installed.
+- **Frame/GC CSV profile:** the same session writes `optimizer-v11-frames-*.csv` with ten-frame-average FPS/frame-time plus GC generation counts and managed heap. FPS is actual rendered-frame cadence, **not** simulation speed; no game-speed metric is inferred.
+- **Update intervals:** per-system controls default to 1 (vanilla). All simulation-critical/global schedulers are pinned to interval 1. The benchmark temporarily removes interval patches to time unthrottled gameplay and restores them after completion.
+- **No gameplay optimizations** (BFR, EBR, preview, fauna, soil, SuperCursor, TimberPhysics catch-up/collider, GC tweaks), no startup guard or save serialization patches.
+- **No always-on tracing:** profiler hooks are installed only during a requested benchmark. The full historical diagnostic and experiment sources remain on the original parent branch; heavy legacy profilers are not installed in the isolated branch.
+
+The benchmark's existing dispatcher instrumentation calls original tick/update methods via validated reflected dispatch. In-game verification is still required even if GitHub Actions succeeds.
+
+## Running alongside TB Optimizer
+
+**Keep both mods enabled.** This port profiles the running colony, while [TB Optimizer](https://github.com/tharbad08/TB-Optimizer) applies stable, individually configurable fixes. Their mod IDs, DLL assembly names and Harmony owners are distinct.
+
+- During benchmarking, this mod temporarily disables **only its own optional update-interval throttles**. TB Optimizer remains active and the CSV measures the actual optimized configuration, not a vanilla baseline.
+- At the default interval **1**, Benchmark & Optimizer does not throttle game systems between benchmark sessions. Avoid increasing intervals when comparing the stable TB Optimizer fixes: skipped callbacks can change simulation behavior.
+- The mods intentionally share observation/optimization targets without sharing ownership: `SingletonLifecycleService.UpdateSingletons` (benchmark dispatcher and frame/GC sampling versus TB Optimizer's optional GC postfix), and TimberPhysics `PhysicsSimulator.UpdateSingleton` (read-only split timings versus TB Optimizer's optional catch-up limiter).
+- This has been checked at the source and Harmony patch-owner level. Full in-game concurrency and benchmark results still require validation.
+
+
+
+## System discovery, filter, and future improvements
+
+**Existing behavior**
+- A startup scan discovers eligible tick/update systems from assemblies that are already loaded.
+- The **120-second benchmark** can discover additional systems encountered during gameplay. Currently it is the way to exercise runtime discovery as well as collect timing data; the initial startup scan alone might not provide the full list.
+- **Neither startup scanning nor benchmarking guarantees discovering every system:** a mod may load later, or its code may never run during the benchmark.
+- The Update Intervals panel includes a filter for system name and mod origin. Its crash fix changes visibility of existing rows instead of destroying and recreating controls during each keystroke.
+- **Refresh detected systems** refreshes the displayed in-memory list; it does not independently perform a new scan. `optimizer-v11.json` stores interval configuration, **not** a complete catalog of detected systems.
+
+**Future work — documentation only, not implemented**
+1. Add a standalone **Detect systems** button that performs safe discovery without needing to start the 120-second benchmark.
+2. Consider triggering discovery **after the save finishes loading** and/or **when opening the mod settings window**, so systems unavailable at initial startup can be detected. Avoid expensive repeated full scans and never disturb simulation/tick scheduling.
+3. Save the **entire discovered-system catalog** to a human-readable, manually editable JSON file, including full type name, mod/assembly origin, protected status, and current interval. Design safe validation/reload of manual edits; manual configuration must never override protections for critical simulation systems.
+4. Make it clear in the UI that **even a separate discovery scan may not detect systems loaded later or never activated**. Offer a way to refresh the catalog as gameplay or mod loading reveals more systems.
+
+These suggestions are future enhancements only; no discovery timing, JSON export, or UI behavior is changed by this note.
+
+
+## Verified source ownership
+
+- [TB-Optimizer](https://github.com/tharbad08/TimberbornMods/tree/TB-Optimizer/BenchmarkAndOptimizerV11Port/Optimizations): gameplay fixes are split into per-mod files there.
+- [TBSave](https://github.com/tharbad08/TimberbornMods/tree/chatgpt/TBSave): save/loading investigations and the Bindito generated-assembly startup guard are preserved there. They are research snapshots, not independently verified isolated save-only binaries.
+- [TBGC](https://github.com/tharbad08/TimberbornMods/tree/chatgpt/TBGC): GC investigation/prototypes are preserved there; this is not proof of an independent live GC optimization.
+- [EBR-Optimizations](https://github.com/tharbad08/TimberbornMods/tree/chatgpt/EBR-Optimizations): legacy EBR-specific experiments and profiling remain preserved; active EBR performance fix is in TB-Optimizer.
+
+See [TICK_SAFETY.md](TICK_SAFETY.md) for protected systems and discovered failure cases.
diff --git a/BenchmarkAndOptimizerV11Port/Runtime.cs b/BenchmarkAndOptimizerV11Port/Runtime.cs
new file mode 100644
index 00000000..325799a6
--- /dev/null
+++ b/BenchmarkAndOptimizerV11Port/Runtime.cs
@@ -0,0 +1,1416 @@
+using System.Collections;
+using System.Reflection;
+using System.Linq.Expressions;
+using System.Runtime.CompilerServices;
+using Newtonsoft.Json;
+using HarmonyLib;
+using Timberborn.ModManagerScene;
+
+namespace BenchmarkAndOptimizerV11;
+
+static class Runtime
+{
+ static readonly object Sync = new();
+ static readonly ConditionalWeakTable