using S3.Core; using UnityEngine; using UnityEngine.Scripting; namespace S3.Modules.BaseGamePerf; public sealed class BaseGamePerfModule : IModule { const string SettingsFile = "S3.basegame.json"; static bool _hasOriginal; static ulong _originalSliceNanoseconds; public static BaseGamePerfSettings Settings { get; private set; } = new(); public BaseGamePerfModule() => Settings = SettingsStore.Load(SettingsFile); public string Id => "basegame"; public string DisplayName => "Base Game Performance"; public string Description => "Evidence-backed vanilla-game hitch controls. Smooths incremental GC and " + "Nature Renderer grass-cell streaming without reducing density, draw distance, " + "resolution, or simulation quality."; public bool Enabled { get => Settings.enabled; set => Settings.enabled = value; } public void OnEnable() { if (!_hasOriginal) { _originalSliceNanoseconds = GarbageCollector.incrementalTimeSliceNanoseconds; _hasOriginal = true; } try { NatureStreamingOptimizer.Enable(); } catch (System.Exception ex) { Log.Warn( "[basegame] Nature streaming smoothing unavailable: " + ex.GetBaseException().Message); } ApplyRuntimeSettings(); } public void OnDisable() { NatureStreamingOptimizer.Disable(); if (_hasOriginal) { GarbageCollector.incrementalTimeSliceNanoseconds = _originalSliceNanoseconds; Log.Info( $"[basegame] Restored incremental GC slice to " + $"{_originalSliceNanoseconds / 1_000_000.0:0.###}ms."); } } public static void ApplyRuntimeSettings() { if (!GarbageCollector.isIncremental) { Log.Warn("[basegame] Unity incremental GC is disabled; smoothing was not applied."); return; } ulong desired = Settings.gcSmoothingEnabled ? (ulong)(Mathf.Clamp(Settings.incrementalSliceMs, 0.25f, 5f) * 1_000_000f) : _originalSliceNanoseconds; GarbageCollector.incrementalTimeSliceNanoseconds = desired; Log.Info( $"[basegame] Incremental GC slice={desired / 1_000_000.0:0.###}ms " + $"(smoothing={Settings.gcSmoothingEnabled})."); NatureStreamingOptimizer.ApplySettings(); } public void SaveSettings() => Persist(); public static void Persist() => SettingsStore.Save(SettingsFile, Settings); public void DrawSettings() => BaseGamePerfSettingsUI.Draw(); }