From ba0ab3bc31063996fce377e92435d9e581c8442c Mon Sep 17 00:00:00 2001 From: gotmachine <24925209+gotmachine@users.noreply.github.com> Date: Sat, 8 Mar 2025 15:06:29 +0100 Subject: [PATCH 1/2] More sensible implementation of the CommNetThrottling patch. CommNet updates are now occuring at a configurable in-game seconds interval (default is 2.5 seconds), instead of a real time interval with a hard minimum of 0.5s. This mean simulation precision will stay consistent when timewarping, as updates will happen more frequently as the timewarp rate goes up, up to every fixed frame when crossing the 125x warp threshold (for the default 2.5s). We also put a upper bound on the update frequency at 50 Hz by checking the fixed/physics frame count (no point in running at stupidly high update rates on high frequency monitors or if framerate isn't locked). --- GameData/KSPCommunityFixes/Settings.cfg | 22 ++++----- .../Performance/CommNetThrottling.cs | 48 +++++++------------ README.md | 2 +- 3 files changed, 27 insertions(+), 45 deletions(-) diff --git a/GameData/KSPCommunityFixes/Settings.cfg b/GameData/KSPCommunityFixes/Settings.cfg index a2cca41..e92f232 100644 --- a/GameData/KSPCommunityFixes/Settings.cfg +++ b/GameData/KSPCommunityFixes/Settings.cfg @@ -372,20 +372,14 @@ KSP_COMMUNITY_FIXES LogGameEventsSubscribers = false } - // Fix CommNet update throttling mechanism that exists in stock but doesn't work correctly. - // This is supposed to prevent full CommNet network updates from happening every frame, but instead to - // to happen at a regular real-world time interval of 5 seconds while in flight. Enabling this throttling - // mechanism has an detrimental impact on the precision of the simulation, so this patch isn't enabled by - // default to avoid issues in mods relying on the stock behavior. Enabling this can provide a decent - // performance uplift in games having a large amount of celestial bodies and/or vessels. - CommNetThrottling = false - - // Interval in real-world seconds between full CommNet network updates. - COMMNET_THROTTLING_SETTINGS - { - unpackedInterval = 5 // interval when the active vessel is not timewarping - packedInterval = 0.5 // interval when the active vessel is timewarping - } + // Implement a throttling mechanism preventing CommNet network updates from happening every frame. + // When this patch is enabled, network updates will only happen at a set interval of in-game seconds, + // defined by the `CommNetThrottlingUpdateInterval` setting (default is 2.5s). This patch will cause + // events such as line of sight loss or acquisition, or comm link changes to happen with a delay, but + // provide a significant performance uplift in games having a large amount of celestial bodies and/or + // vessels. + CommNetThrottling = true + CommNetThrottlingUpdateInterval = 2.5 // This tweak eliminates KSP's stock behavior of saving every time // you exit a UI-only space center building (AC, MC, etc) diff --git a/KSPCommunityFixes/Performance/CommNetThrottling.cs b/KSPCommunityFixes/Performance/CommNetThrottling.cs index 04c977c..5f25eb7 100644 --- a/KSPCommunityFixes/Performance/CommNetThrottling.cs +++ b/KSPCommunityFixes/Performance/CommNetThrottling.cs @@ -1,45 +1,33 @@ -using HarmonyLib; -using System.Collections.Generic; -using UnityEngine; - -namespace KSPCommunityFixes.Performance +namespace KSPCommunityFixes.Performance { class CommNetThrottling : BasePatch { - private static double packedInterval = 0.5; - private static double unpackedInterval = 5.0; + private static double updateInterval = 2.5; + private static long lastUpdateFixedFrame = 0L; protected override void ApplyPatches() { - ConfigNode settingsNode = KSPCommunityFixes.SettingsNode.GetNode("COMMNET_THROTTLING_SETTINGS"); - - if (settingsNode != null) - { - settingsNode.TryGetValue("packedInterval", ref packedInterval); - settingsNode.TryGetValue("unpackedInterval", ref unpackedInterval); - } - - AddPatch(PatchType.Prefix, typeof(CommNet.CommNetNetwork), nameof(CommNet.CommNetNetwork.Update)); + KSPCommunityFixes.SettingsNode.TryGetValue("CommNetThrottlingUpdateInterval", ref updateInterval); + AddPatch(PatchType.Override, typeof(CommNet.CommNetNetwork), nameof(CommNet.CommNetNetwork.Update)); } - static bool CommNetNetwork_Update_Prefix(CommNet.CommNetNetwork __instance) + static void CommNetNetwork_Update_Override(CommNet.CommNetNetwork commNetNetwork) { - if (!__instance.queueRebuild && !__instance.commNet.IsDirty) + double currentTime = Planetarium.GetUniversalTime(); + double interval = currentTime - commNetNetwork.prevUpdate; + if (!commNetNetwork.queueRebuild && !commNetNetwork.commNet.IsDirty + && interval >= 0.0 + && (interval < updateInterval || KSPCommunityFixes.FixedUpdateCount == lastUpdateFixedFrame)) { - double timeSinceLastUpdate = Time.timeSinceLevelLoad - __instance.prevUpdate; - - if (FlightGlobals.ActiveVessel != null) - { - double interval = FlightGlobals.ActiveVessel.packed ? packedInterval : unpackedInterval; - if (timeSinceLastUpdate < interval) - { - __instance.graphDirty = true; - return false; - } - } + commNetNetwork.graphDirty = true; + return; } - return true; + lastUpdateFixedFrame = KSPCommunityFixes.FixedUpdateCount; + commNetNetwork.commNet.Rebuild(); + commNetNetwork.prevUpdate = currentTime; + commNetNetwork.graphDirty = false; + commNetNetwork.queueRebuild = false; } } } diff --git a/README.md b/README.md index 30b5f26..349853f 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ User options are available from the "ESC" in-game settings menu :
= 0.0 - && (interval < updateInterval || KSPCommunityFixes.FixedUpdateCount == lastUpdateFixedFrame)) + && currentGameTimeInterval >= 0.0 + && (currentGameTimeInterval < maxGameTimeInterval || realTimeUpdateTimer.ElapsedMilliseconds < minRealTimeInterval)) { commNetNetwork.graphDirty = true; return; } - lastUpdateFixedFrame = KSPCommunityFixes.FixedUpdateCount; + // UnityEngine.Debug.Log($"CommNet update interval : {realTimeUpdateTimer.Elapsed.TotalMilliseconds:F0}ms"); + commNetNetwork.commNet.Rebuild(); - commNetNetwork.prevUpdate = currentTime; + realTimeUpdateTimer.Restart(); + commNetNetwork.prevUpdate = currentGameTime; commNetNetwork.graphDirty = false; commNetNetwork.queueRebuild = false; } diff --git a/README.md b/README.md index 349853f..b432edd 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ User options are available from the "ESC" in-game settings menu :