Skip to content

Commit

Permalink
FlightIntegrator and friends micro-optimization Round 2 (#257)
Browse files Browse the repository at this point in the history
Various perf fixes :
- **ModuleDockingNodeFindOtherNodesFaster** : Faster lookup of other docking nodes.
- **CollisionEnhancerFastUpdate** : Optimization of the `CollisionEnhancer` component (responsible for part to terrain collision detection).
- **PartSystemsFastUpdate** : Optimization of various flight scene auxiliary subsystems : temperature gauges, highlighter, strut position tracking...
- **MinorPerfTweaks** : Various small performance patches (volume normalizer, eva module checks)
- **FlightIntegratorPerf** : General micro-optimization of `FlightIntegrator` and `VesselPrecalculate`, components in charge of most of heavy lifting for newtonian physics as well as atmospheric and thermal physics.
- **FloatingOriginPerf** : General micro-optimization of floating origin shifts. Main benefit is in large particle count situations (ie, launches with many engines) but this helps a bit in other cases as well.

There are two other (not really related) changes in this PR : 
- Small internal refactor of the patching infrastructure for less verbose patch declaration.
- Introduced a new "override" patch type, basically an automatic transpiler allowing to replace a method body with another. This has a little less overhead than a prefix doing the same thing, and allow for other patches (including non-KSPCF ones) to prefix the patched method as usual. This was surprisingly difficult to put together and to get right, and while I have done quite a bit of validation, it wouldn't surprise me if further issues arise with this. For now, this new patch type is only used by the patches in this PR, but if everything works out, updating all the existing "prefix return false" patches would be nice.
  • Loading branch information
JonnyOThan authored Oct 12, 2024
1 parent 6948692 commit 6e65ef2
Show file tree
Hide file tree
Showing 108 changed files with 4,291 additions and 2,098 deletions.
25 changes: 21 additions & 4 deletions GameData/KSPCommunityFixes/Settings.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -426,13 +426,30 @@ KSP_COMMUNITY_FIXES
// Improve engine exhaust damage and solar panel line of sight raycasts performance by avoiding extra physics
// state synchronization and caching solar panels scaled space raycasts results.
OptimizedModuleRaycasts = true
// Faster and minimal GC allocation replacements for Part FindModelTransform*() and FindHeirarchyTransform*()
FasterPartFindTransform = true
// General micro-optimization of FlightIntegrator and VesselPrecalculate, significantely increase
// framerate in large part count situations.
FlightPerf = true
// Faster lookup of other docking nodes
ModuleDockingNodeFindOtherNodesFaster = true
// Micro-optimizations of the CollisionEnhancer component, significant impact in high part count situations
CollisionEnhancerFastUpdate = true
// Micro-optimization of various flight scene auxiliary subsystems : temperature gauges, highlighter,
// strut position tracking...
PartSystemsFastUpdate = true
// Various small performance patches (volume normalizer, eva module checks)
MinorPerfTweaks = true
// General micro-optimization of FlightIntegrator and VesselPrecalculate. This has a significant impact in
// large part count situations, and especially in atmospheric situations.
FlightIntegratorPerf = false
// General micro-optimization of floating origin shifts. Main benefit is in large particle count situations
// but this helps a bit in other cases as well.
FloatingOriginPerf = false
// ##########################
// Modding
Expand Down
546 changes: 515 additions & 31 deletions KSPCommunityFixes/BasePatch.cs

Large diffs are not rendered by default.

9 changes: 4 additions & 5 deletions KSPCommunityFixes/BugFixes/AsteroidInfiniteMining.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ class AsteroidInfiniteMining : BasePatch
{
protected override Version VersionMin => new Version(1, 10, 0);

protected override void ApplyPatches(List<PatchInfo> patches)
protected override void ApplyPatches()
{
patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AccessTools.PropertySetter(typeof(ModuleSpaceObjectInfo), nameof(ModuleSpaceObjectInfo.currentMassVal)),
this, nameof(ModuleSpaceObjectInfo_currentMassVal_Setter_Prefix)));
AddPatch(PatchType.Prefix,
AccessTools.PropertySetter(typeof(ModuleSpaceObjectInfo), nameof(ModuleSpaceObjectInfo.currentMassVal)),
nameof(ModuleSpaceObjectInfo_currentMassVal_Setter_Prefix));
}

static bool ModuleSpaceObjectInfo_currentMassVal_Setter_Prefix(ModuleSpaceObjectInfo __instance, double value)
Expand Down
14 changes: 4 additions & 10 deletions KSPCommunityFixes/BugFixes/AsteroidSpawnerUniqueFlightId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,9 @@ class AsteroidSpawnerUniqueFlightId : BasePatch
{
protected override Version VersionMin => new Version(1, 8, 0);

protected override void ApplyPatches(List<PatchInfo> patches)
protected override void ApplyPatches()
{
patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AccessTools.Method(typeof(ScenarioDiscoverableObjects), nameof(ScenarioDiscoverableObjects.SpawnAsteroid)),
this));
AddPatch(PatchType.Prefix, typeof(ScenarioDiscoverableObjects), nameof(ScenarioDiscoverableObjects.SpawnAsteroid));
}

static bool ScenarioDiscoverableObjects_SpawnAsteroid_Prefix(ScenarioDiscoverableObjects __instance)
Expand Down Expand Up @@ -53,12 +50,9 @@ class CometSpawnerUniqueFlightId : BasePatch
{
protected override Version VersionMin => new Version(1, 10, 0);

protected override void ApplyPatches(List<PatchInfo> patches)
protected override void ApplyPatches()
{
patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AccessTools.Method(typeof(ScenarioDiscoverableObjects), nameof(ScenarioDiscoverableObjects.SpawnComet), new Type[] {typeof(CometOrbitType) }),
this));
AddPatch(PatchType.Prefix, typeof(ScenarioDiscoverableObjects), nameof(ScenarioDiscoverableObjects.SpawnComet), new Type[] {typeof(CometOrbitType) });
}

static bool ScenarioDiscoverableObjects_SpawnComet_Prefix(ScenarioDiscoverableObjects __instance, CometOrbitType cometType)
Expand Down
7 changes: 2 additions & 5 deletions KSPCommunityFixes/BugFixes/AutoStrutDrift.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,9 @@ public class AutoStrutDrift : BasePatch
{
protected override Version VersionMin => new Version(1, 8, 0);

protected override void ApplyPatches(List<PatchInfo> patches)
protected override void ApplyPatches()
{
patches.Add(new PatchInfo(
PatchMethodType.Postfix,
AccessTools.Method(typeof(Part), "SecureAutoStrut", new Type[]{typeof(Part), typeof(AttachNode), typeof(AttachNode), typeof(bool)}),
this));
AddPatch(PatchType.Postfix, typeof(Part), "SecureAutoStrut", new Type[]{typeof(Part), typeof(AttachNode), typeof(AttachNode), typeof(bool)});
}

static void Part_SecureAutoStrut_Postfix(Part __instance, Part anchor, ref PartJoint __result)
Expand Down
12 changes: 3 additions & 9 deletions KSPCommunityFixes/BugFixes/ChutePhantomSymmetry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,11 @@ internal class ChutePhantomSymmetry : BasePatch
{
protected override Version VersionMin => new Version(1, 10, 0);

protected override void ApplyPatches(List<PatchInfo> patches)
protected override void ApplyPatches()
{
patches.Add(new PatchInfo(
PatchMethodType.Postfix,
AccessTools.Method(typeof(ModuleParachute), nameof(ModuleParachute.OnStart)),
this));
AddPatch(PatchType.Postfix, typeof(ModuleParachute), nameof(ModuleParachute.OnStart));

patches.Add(new PatchInfo(
PatchMethodType.Postfix,
AccessTools.Method(typeof(ModuleParachute), nameof(ModuleParachute.OnDestroy)),
this));
AddPatch(PatchType.Postfix, typeof(ModuleParachute), nameof(ModuleParachute.OnDestroy));
}

private static void ModuleParachute_OnStart_Postfix(ModuleParachute __instance, StartState state)
Expand Down
7 changes: 2 additions & 5 deletions KSPCommunityFixes/BugFixes/CometMiningNotRemovingMass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,9 @@ class CometMiningNotRemovingMass : BasePatch
{
protected override Version VersionMin => new Version(1, 12, 2);

protected override void ApplyPatches(List<PatchInfo> patches)
protected override void ApplyPatches()
{
patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AccessTools.Method(typeof(ModuleComet), nameof(ModuleComet.GetModuleMass)),
this));
AddPatch(PatchType.Prefix, typeof(ModuleComet), nameof(ModuleComet.GetModuleMass));
}

static bool ModuleComet_GetModuleMass_Prefix(ModuleComet __instance, float defaultMass, out float __result)
Expand Down
7 changes: 2 additions & 5 deletions KSPCommunityFixes/BugFixes/CorrectDragForFlags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,9 @@ internal class CorrectDragForFlags : BasePatch
{
protected override Version VersionMin => new Version(1, 12, 3);

protected override void ApplyPatches(List<PatchInfo> patches)
protected override void ApplyPatches()
{
patches.Add(new PatchInfo(
PatchMethodType.Postfix,
AccessTools.Method(typeof(FlagDecalBackground), nameof(FlagDecalBackground.EnableCurrentFlagMesh)),
this));
AddPatch(PatchType.Postfix, typeof(FlagDecalBackground), nameof(FlagDecalBackground.EnableCurrentFlagMesh));
}

static void FlagDecalBackground_EnableCurrentFlagMesh_Postfix(FlagDecalBackground __instance)
Expand Down
49 changes: 14 additions & 35 deletions KSPCommunityFixes/BugFixes/DeltaVHideWhenDisabled.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,21 @@ public class DeltaVHideWhenDisabled : BasePatch
{
protected override Version VersionMin => new Version(1, 12, 0);

protected override void ApplyPatches(List<PatchInfo> patches)
protected override void ApplyPatches()
{
patches.Add(new PatchInfo(
PatchMethodType.Postfix,
AccessTools.Method(typeof(StageGroup), "Awake"),
this));

patches.Add(new PatchInfo(
PatchMethodType.Postfix,
AccessTools.Method(typeof(StageManager), "Awake"),
this));

patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AccessTools.Method(typeof(StageGroup), "ToggleInfoPanel", new Type[] { typeof(bool) }),
this));

patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AccessTools.Method(typeof(NavBallBurnVector), "onGameSettingsApplied"),
this));

patches.Add(new PatchInfo(
PatchMethodType.Postfix,
AccessTools.Method(typeof(NavBallBurnVector), "onGameSettingsApplied"),
this));

patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AccessTools.Method(typeof(NavBallBurnVector), "LateUpdate"),
this));

patches.Add(new PatchInfo(
PatchMethodType.Postfix,
AccessTools.Method(typeof(NavBallBurnVector), "LateUpdate"),
this));
AddPatch(PatchType.Postfix, typeof(StageGroup), "Awake");

AddPatch(PatchType.Postfix, typeof(StageManager), "Awake");

AddPatch(PatchType.Prefix, typeof(StageGroup), "ToggleInfoPanel", new Type[] { typeof(bool) });

AddPatch(PatchType.Prefix, typeof(NavBallBurnVector), "onGameSettingsApplied");

AddPatch(PatchType.Postfix, typeof(NavBallBurnVector), "onGameSettingsApplied");

AddPatch(PatchType.Prefix, typeof(NavBallBurnVector), "LateUpdate");

AddPatch(PatchType.Postfix, typeof(NavBallBurnVector), "LateUpdate");
}

static void StageGroup_Awake_Postfix(StageGroup __instance)
Expand Down
8 changes: 2 additions & 6 deletions KSPCommunityFixes/BugFixes/DockingPortConserveMomentum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class DockingPortConserveMomentum : BasePatch
{
protected override Version VersionMin => new Version(1, 12, 3);

protected override void ApplyPatches(List<PatchInfo> patches)
protected override void ApplyPatches()
{
// We need to patch a closure, which doesn't have a stable method name.
// So we patch everything that *might* be the closure we are looking for,
Expand All @@ -22,11 +22,7 @@ protected override void ApplyPatches(List<PatchInfo> patches)
{
if (methodName.StartsWith("<SetupFSM>") && !methodName.Contains("_Patch"))
{
patches.Add(new PatchInfo(
PatchMethodType.Transpiler,
AccessTools.Method(typeof(ModuleDockingNode), methodName),
this,
"ModuleDockingNode_SetupFSMClosure_Transpiler"));
AddPatch(PatchType.Transpiler, typeof(ModuleDockingNode), methodName, "ModuleDockingNode_SetupFSMClosure_Transpiler");
}
}
}
Expand Down
96 changes: 29 additions & 67 deletions KSPCommunityFixes/BugFixes/DockingPortRotationDriftAndFixes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,77 +11,39 @@ class DockingPortRotationDriftAndFixes : BasePatch
{
protected override Version VersionMin => new Version(1, 12, 3);

protected override void ApplyPatches(List<PatchInfo> patches)
protected override void ApplyPatches()
{
patches.Add(new PatchInfo(
PatchMethodType.Transpiler,
AccessTools.Method(typeof(ModuleDockingNode), nameof(ModuleDockingNode.OnLoad)),
this));

patches.Add(new PatchInfo(
PatchMethodType.Postfix,
AccessTools.Method(typeof(ModuleDockingNode), nameof(ModuleDockingNode.OnSave)),
this));

patches.Add(new PatchInfo(
PatchMethodType.Postfix,
AccessTools.Method(typeof(ModuleDockingNode), nameof(ModuleDockingNode.OnStart)),
this));

patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AccessTools.Method(typeof(ModuleDockingNode), nameof(ModuleDockingNode.OnStartFinished)),
this));

patches.Add(new PatchInfo(
PatchMethodType.Postfix,
AccessTools.Method(typeof(ModuleDockingNode), nameof(ModuleDockingNode.OnDestroy)),
this));

patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AddPatch(PatchType.Transpiler, typeof(ModuleDockingNode), nameof(ModuleDockingNode.OnLoad));

AddPatch(PatchType.Postfix, typeof(ModuleDockingNode), nameof(ModuleDockingNode.OnSave));

AddPatch(PatchType.Postfix, typeof(ModuleDockingNode), nameof(ModuleDockingNode.OnStart));

AddPatch(PatchType.Prefix, typeof(ModuleDockingNode), nameof(ModuleDockingNode.OnStartFinished));

AddPatch(PatchType.Postfix, typeof(ModuleDockingNode), nameof(ModuleDockingNode.OnDestroy));

AddPatch(PatchType.Prefix,
AccessTools.PropertyGetter(typeof(ModuleDockingNode), nameof(ModuleDockingNode.RotationJoint)),
this, nameof(ModuleDockingNode_RotationJoint_Prefix)));
nameof(ModuleDockingNode_RotationJoint_Prefix));

patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AddPatch(PatchType.Prefix,
AccessTools.PropertyGetter(typeof(ModuleDockingNode), nameof(ModuleDockingNode.VisualTargetAngle)),
this, nameof(ModuleDockingNode_VisualTargetAngle_Prefix)));

patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AccessTools.Method(typeof(ModuleDockingNode), nameof(ModuleDockingNode.OnPartUnpack)),
this));

patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AccessTools.Method(typeof(ModuleDockingNode), nameof(ModuleDockingNode.UpdatePAWUI)),
this));

patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AccessTools.Method(typeof(ModuleDockingNode), nameof(ModuleDockingNode.UpdateAlignmentRotation)),
this));

patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AccessTools.Method(typeof(ModuleDockingNode), nameof(ModuleDockingNode.ApplyCoordsUpdate)),
this));

patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AccessTools.Method(typeof(ModuleDockingNode), nameof(ModuleDockingNode.SetJointHighLowLimits)),
this));

patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AccessTools.Method(typeof(ModuleDockingNode), nameof(ModuleDockingNode.ModifyLocked)),
this));

patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AccessTools.Method(typeof(ModuleDockingNode), nameof(ModuleDockingNode.IsJointUnlocked)),
this));
nameof(ModuleDockingNode_VisualTargetAngle_Prefix));

AddPatch(PatchType.Prefix, typeof(ModuleDockingNode), nameof(ModuleDockingNode.OnPartUnpack));

AddPatch(PatchType.Prefix, typeof(ModuleDockingNode), nameof(ModuleDockingNode.UpdatePAWUI));

AddPatch(PatchType.Prefix, typeof(ModuleDockingNode), nameof(ModuleDockingNode.UpdateAlignmentRotation));

AddPatch(PatchType.Prefix, typeof(ModuleDockingNode), nameof(ModuleDockingNode.ApplyCoordsUpdate));

AddPatch(PatchType.Prefix, typeof(ModuleDockingNode), nameof(ModuleDockingNode.SetJointHighLowLimits));

AddPatch(PatchType.Prefix, typeof(ModuleDockingNode), nameof(ModuleDockingNode.ModifyLocked));

AddPatch(PatchType.Prefix, typeof(ModuleDockingNode), nameof(ModuleDockingNode.IsJointUnlocked));

GameEvents.onGameSceneLoadRequested.Add(OnSceneSwitch);
}
Expand Down
7 changes: 2 additions & 5 deletions KSPCommunityFixes/BugFixes/DoubleCurvePreserveTangents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,9 @@ class DoubleCurvePreserveTangents : BasePatch
{
protected override Version VersionMin => new Version(1, 8, 0);

protected override void ApplyPatches(List<PatchInfo> patches)
protected override void ApplyPatches()
{
patches.Add(new PatchInfo(
PatchMethodType.Transpiler,
AccessTools.Method(typeof(DoubleCurve), nameof(DoubleCurve.RecomputeTangents)),
this));
AddPatch(PatchType.Transpiler, typeof(DoubleCurve), nameof(DoubleCurve.RecomputeTangents));
}

static IEnumerable<CodeInstruction> DoubleCurve_RecomputeTangents_Transpiler(IEnumerable<CodeInstruction> instructions)
Expand Down
7 changes: 2 additions & 5 deletions KSPCommunityFixes/BugFixes/EVAConstructionMass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,9 @@ class EVAConstructionMass : BasePatch
{
protected override Version VersionMin => new Version(1, 12, 3);

protected override void ApplyPatches(List<PatchInfo> patches)
protected override void ApplyPatches()
{
patches.Add(new PatchInfo(
PatchMethodType.Transpiler,
AccessTools.Method(typeof(EVAConstructionModeEditor), nameof(EVAConstructionModeEditor.PickupPart)),
this));
AddPatch(PatchType.Transpiler, typeof(EVAConstructionModeEditor), nameof(EVAConstructionModeEditor.PickupPart));
}

// the stock code sets selectedpart.mass to the prefab mass, which breaks terribly in cases where there are mass modifiers involved
Expand Down
7 changes: 2 additions & 5 deletions KSPCommunityFixes/BugFixes/EVAKerbalRecovery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,9 @@ public class EVAKerbalRecovery : BasePatch
{
protected override Version VersionMin => new Version(1, 11, 0);

protected override void ApplyPatches(List<PatchInfo> patches)
protected override void ApplyPatches()
{
patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AccessTools.Method(typeof(ProtoVessel), nameof(ProtoVessel.GetAllProtoPartsIncludingCargo)),
this));
AddPatch(PatchType.Prefix, typeof(ProtoVessel), nameof(ProtoVessel.GetAllProtoPartsIncludingCargo));
}

private static bool ProtoVessel_GetAllProtoPartsIncludingCargo_Prefix(ProtoVessel __instance, out List<ProtoPartSnapshot> __result)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,9 @@ class EnginePlateAirstreamShieldedTopPart : BasePatch
{
protected override Version VersionMin => new Version(1, 11, 0);

protected override void ApplyPatches(List<PatchInfo> patches)
protected override void ApplyPatches()
{
patches.Add(new PatchInfo(
PatchMethodType.Prefix,
AccessTools.Method(typeof(ModuleDecouplerBase), nameof(ModuleDecouplerBase.SetAirstream)),
this));
AddPatch(PatchType.Prefix, typeof(ModuleDecouplerBase), nameof(ModuleDecouplerBase.SetAirstream));
}

static bool ModuleDecouplerBase_SetAirstream_Prefix(ModuleDecouplerBase __instance, bool enclosed)
Expand Down
Loading

0 comments on commit 6e65ef2

Please sign in to comment.