Skip to content

Commit 9010ae1

Browse files
authored
More balanced CommNetThrottling performance patch (#299)
Revamped mechanism that use an upper limit interval between updates in an in-game time set to 2.5 seconds, which is more acceptable for gameplay purposes. It also put an upper bound on the real time update frequency set to 50 hz (20 ms minimum interval), as there is no point in running at stupidly high update frequency on high frequency monitors or if the framerate isn't locked (manually or through V-Sync). That last setting can be increased to up to 500 or even 1000 ms in case the user doesn't care about simulation precision during timewarp and want to avoid the continuous performance hit in such cases. This PR also enable the patch by default.
1 parent 15c2c0e commit 9010ae1

File tree

3 files changed

+40
-34
lines changed

3 files changed

+40
-34
lines changed

GameData/KSPCommunityFixes/Settings.cfg

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -372,19 +372,25 @@ KSP_COMMUNITY_FIXES
372372
LogGameEventsSubscribers = false
373373
}
374374
375-
// Fix CommNet update throttling mechanism that exists in stock but doesn't work correctly.
376-
// This is supposed to prevent full CommNet network updates from happening every frame, but instead to
377-
// to happen at a regular real-world time interval of 5 seconds while in flight. Enabling this throttling
378-
// mechanism has an detrimental impact on the precision of the simulation, so this patch isn't enabled by
379-
// default to avoid issues in mods relying on the stock behavior. Enabling this can provide a decent
380-
// performance uplift in games having a large amount of celestial bodies and/or vessels.
381-
CommNetThrottling = false
382-
383-
// Interval in real-world seconds between full CommNet network updates.
375+
// Implement a throttling mechanism preventing CommNet network updates from happening every frame.
376+
// When this patch is enabled, network updates will only happen at a set interval of in-game seconds,
377+
// defined by below settings. This patch will cause events such as line of sight loss or acquisition,
378+
// or comm link changes to happen with a delay, but provide a significant performance uplift in games
379+
// having a large amount of celestial bodies and/or vessels.
380+
CommNetThrottling = true
381+
384382
COMMNET_THROTTLING_SETTINGS
385383
{
386-
unpackedInterval = 5 // interval when the active vessel is not timewarping
387-
packedInterval = 0.5 // interval when the active vessel is timewarping
384+
// Maximum duration in in-game seconds between CommNet updates.
385+
// Increasing it further than the 2.5s default won't have any effect on framerate and will make
386+
// CommNet situation changes (such as loss or acqusition of signal) increasingly sluggish.
387+
maxGameTimeInterval = 2.5
388+
389+
// Minimum duration in real world *milliseconds* between CommNet updates.
390+
// Increasing it will only affect medium to fast timewarp situations, and will improve framerate
391+
// and significately reduce simulation precision. Recommended value is either 20 or 500 to 1000,
392+
// values in between will likely result in stuttery framerate and no perceptible improvement.
393+
minRealTimeInterval = 20
388394
}
389395

390396
// This tweak eliminates KSP's stock behavior of saving every time
Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,45 @@
1-
using HarmonyLib;
2-
using System.Collections.Generic;
3-
using UnityEngine;
1+
using System.Diagnostics;
42

53
namespace KSPCommunityFixes.Performance
64
{
75
class CommNetThrottling : BasePatch
86
{
9-
private static double packedInterval = 0.5;
10-
private static double unpackedInterval = 5.0;
7+
private static double maxGameTimeInterval = 2.5;
8+
private static long minRealTimeInterval = 20;
9+
private static Stopwatch realTimeUpdateTimer = new Stopwatch();
1110

1211
protected override void ApplyPatches()
1312
{
1413
ConfigNode settingsNode = KSPCommunityFixes.SettingsNode.GetNode("COMMNET_THROTTLING_SETTINGS");
1514

1615
if (settingsNode != null)
1716
{
18-
settingsNode.TryGetValue("packedInterval", ref packedInterval);
19-
settingsNode.TryGetValue("unpackedInterval", ref unpackedInterval);
17+
settingsNode.TryGetValue("maxGameTimeInterval", ref maxGameTimeInterval);
18+
settingsNode.TryGetValue("minRealTimeInterval", ref minRealTimeInterval);
2019
}
2120

22-
AddPatch(PatchType.Prefix, typeof(CommNet.CommNetNetwork), nameof(CommNet.CommNetNetwork.Update));
21+
AddPatch(PatchType.Override, typeof(CommNet.CommNetNetwork), nameof(CommNet.CommNetNetwork.Update));
2322
}
2423

25-
static bool CommNetNetwork_Update_Prefix(CommNet.CommNetNetwork __instance)
24+
static void CommNetNetwork_Update_Override(CommNet.CommNetNetwork commNetNetwork)
2625
{
27-
if (!__instance.queueRebuild && !__instance.commNet.IsDirty)
26+
double currentGameTime = Planetarium.GetUniversalTime();
27+
double currentGameTimeInterval = currentGameTime - commNetNetwork.prevUpdate;
28+
if (!commNetNetwork.queueRebuild && !commNetNetwork.commNet.IsDirty
29+
&& currentGameTimeInterval >= 0.0
30+
&& (currentGameTimeInterval < maxGameTimeInterval || realTimeUpdateTimer.ElapsedMilliseconds < minRealTimeInterval))
2831
{
29-
double timeSinceLastUpdate = Time.timeSinceLevelLoad - __instance.prevUpdate;
30-
31-
if (FlightGlobals.ActiveVessel != null)
32-
{
33-
double interval = FlightGlobals.ActiveVessel.packed ? packedInterval : unpackedInterval;
34-
if (timeSinceLastUpdate < interval)
35-
{
36-
__instance.graphDirty = true;
37-
return false;
38-
}
39-
}
32+
commNetNetwork.graphDirty = true;
33+
return;
4034
}
4135

42-
return true;
36+
// UnityEngine.Debug.Log($"CommNet update interval : {realTimeUpdateTimer.Elapsed.TotalMilliseconds:F0}ms");
37+
38+
commNetNetwork.commNet.Rebuild();
39+
realTimeUpdateTimer.Restart();
40+
commNetNetwork.prevUpdate = currentGameTime;
41+
commNetNetwork.graphDirty = false;
42+
commNetNetwork.queueRebuild = false;
4343
}
4444
}
4545
}

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ User options are available from the "ESC" in-game settings menu :<br/><img src="
121121
- [**MemoryLeaks**](https://github.com/KSPModdingLibs/KSPCommunityFixes/issues/49) [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.
122122
- [**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.
123123
- [**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.
124-
- [**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.
124+
- [**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.
125125
- [**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.
126126
- [**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.
127127
- [**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.

0 commit comments

Comments
 (0)