diff --git a/GameData/KSPCommunityFixes/Settings.cfg b/GameData/KSPCommunityFixes/Settings.cfg
index a2cca41..51b457b 100644
--- a/GameData/KSPCommunityFixes/Settings.cfg
+++ b/GameData/KSPCommunityFixes/Settings.cfg
@@ -372,19 +372,25 @@ 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.
+ // 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 below settings. 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
+
COMMNET_THROTTLING_SETTINGS
{
- unpackedInterval = 5 // interval when the active vessel is not timewarping
- packedInterval = 0.5 // interval when the active vessel is timewarping
+ // Maximum duration in in-game seconds between CommNet updates.
+ // Increasing it further than the 2.5s default won't have any effect on framerate and will make
+ // CommNet situation changes (such as loss or acqusition of signal) increasingly sluggish.
+ maxGameTimeInterval = 2.5
+
+ // Minimum duration in real world *milliseconds* between CommNet updates.
+ // Increasing it will only affect medium to fast timewarp situations, and will improve framerate
+ // and significately reduce simulation precision. Recommended value is either 20 or 500 to 1000,
+ // values in between will likely result in stuttery framerate and no perceptible improvement.
+ minRealTimeInterval = 20
}
// This tweak eliminates KSP's stock behavior of saving every time
diff --git a/KSPCommunityFixes/Performance/CommNetThrottling.cs b/KSPCommunityFixes/Performance/CommNetThrottling.cs
index 04c977c..b5763f2 100644
--- a/KSPCommunityFixes/Performance/CommNetThrottling.cs
+++ b/KSPCommunityFixes/Performance/CommNetThrottling.cs
@@ -1,13 +1,12 @@
-using HarmonyLib;
-using System.Collections.Generic;
-using UnityEngine;
+using System.Diagnostics;
namespace KSPCommunityFixes.Performance
{
class CommNetThrottling : BasePatch
{
- private static double packedInterval = 0.5;
- private static double unpackedInterval = 5.0;
+ private static double maxGameTimeInterval = 2.5;
+ private static long minRealTimeInterval = 20;
+ private static Stopwatch realTimeUpdateTimer = new Stopwatch();
protected override void ApplyPatches()
{
@@ -15,31 +14,32 @@ protected override void ApplyPatches()
if (settingsNode != null)
{
- settingsNode.TryGetValue("packedInterval", ref packedInterval);
- settingsNode.TryGetValue("unpackedInterval", ref unpackedInterval);
+ settingsNode.TryGetValue("maxGameTimeInterval", ref maxGameTimeInterval);
+ settingsNode.TryGetValue("minRealTimeInterval", ref minRealTimeInterval);
}
- AddPatch(PatchType.Prefix, typeof(CommNet.CommNetNetwork), nameof(CommNet.CommNetNetwork.Update));
+ 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 currentGameTime = Planetarium.GetUniversalTime();
+ double currentGameTimeInterval = currentGameTime - commNetNetwork.prevUpdate;
+ if (!commNetNetwork.queueRebuild && !commNetNetwork.commNet.IsDirty
+ && currentGameTimeInterval >= 0.0
+ && (currentGameTimeInterval < maxGameTimeInterval || realTimeUpdateTimer.ElapsedMilliseconds < minRealTimeInterval))
{
- 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;
+ // UnityEngine.Debug.Log($"CommNet update interval : {realTimeUpdateTimer.Elapsed.TotalMilliseconds:F0}ms");
+
+ commNetNetwork.commNet.Rebuild();
+ realTimeUpdateTimer.Restart();
+ commNetNetwork.prevUpdate = currentGameTime;
+ commNetNetwork.graphDirty = false;
+ commNetNetwork.queueRebuild = false;
}
}
}
diff --git a/README.md b/README.md
index 30b5f26..b432edd 100644
--- a/README.md
+++ b/README.md
@@ -121,7 +121,7 @@ User options are available from the "ESC" in-game settings menu :
 [KSP 1.12.0 - 1.12.5]<br/>Fix a bunch of managed memory leaks, mainly by proactively removing `GameEvents` delegates originating from destroyed `UnityEngine.Object` instances on scene switches. Will log detected leaks and memory usage. Also see`Settings.cfg` to enable advanced logging options that can be useful to hunt down memory leaks in mods.
- [**ProgressTrackingSpeedBoost**](https://github.com/KSPModdingLibs/KSPCommunityFixes/pull/57) [KSP 1.12.0 - 1.12.5]<br/>Remove unused ProgressTracking update handlers. Provides a very noticeable performance uplift in career games having a large amount of celestial bodies and/or vessels.
- [**DisableMapUpdateInFlight**](https://github.com/KSPModdingLibs/KSPCommunityFixes/issues/59) [KSP 1.8.0 - 1.12.5]<br/>Disable the update of orbit lines and markers in flight when the map view isn't shown. Provides decent performance gains in games having a large amount of celestial bodies and/or vessels.
-- [**CommNetThrottling**](https://github.com/KSPModdingLibs/KSPCommunityFixes/issues/56) [KSP 1.12.0 - 1.12.5]<br/>Disabled by default, you can enable it with a MM patch. Prevent full CommNet network updates from happening every frame, but instead to happen at a regular real-world time interval of 5 seconds while in flight. Enabling this can provide a decent performance uplift in games having an large amount of celestial bodies and/or vessels, but has a detrimental impact on the precision of the simulation and can potentially cause issues with mods relying on the stock behavior.
+- [**CommNetThrottling**](https://github.com/KSPModdingLibs/KSPCommunityFixes/issues/56) [KSP 1.12.0 - 1.12.5]<br/>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 (default is 2.5s, configurable in `Settings.cfg`). This patch will cause events such as line of sight loss or acquisition, or comm link changes to happen with a slight delay, but provide a significant performance uplift in games having a large amount of celestial bodies and/or vessels.
- [**AsteroidAndCometDrillCache**](https://github.com/KSPModdingLibs/KSPCommunityFixes/pull/67) [KSP 1.12.5]<br/>Reduce constant overhead of ModuleAsteroidDrill and ModuleCometDrill by using the cached asteroid/comet part lookup results from ModuleResourceHarvester. Improves performance with large part count vessels having at least one drill part.
- [**FewerSaves**](https://github.com/KSPModdingLibs/KSPCommunityFixes/pull/80) [KSP 1.8.0 - KSP 1.12.5]<br/>Disables saving on exiting Space Center minor buildings (Mission Control etc) and when deleting vessels in Tracking Station. Disabled by default.
- [**ConfigNodePerf**](https://github.com/KSPModdingLibs/KSPCommunityFixes/pull/88) [see also](https://github.com/KSPModdingLibs/KSPCommunityFixes/pull/90) [KSP 1.8.0 - KSP 1.12.5]<br/>Speeds up many ConfigNode methods, especially reading and writing ConfigNodes.
)