KSPModdingLibs/KSPCommunityFixes

Performance: Ships with large numbers of engines are slow because of interleaved transform updates/raycasts

Closed this issue ยท 5 comments

Engines have to do a raycast to see if the thrust is obstructed. In the stock code this happens in the engine module's FixedUpdate. The problem is that this is basically interleaved with transform updates, and >90% of the cost of the raycasts is in syncing collider transforms. If the engine raycasts were batched together, the sync would only need to happen once and it should be much faster.

image

Yup, that's what we already solved in SolverEngines.
KSP-RO/SolverEngines@b3b7a95

Awesome....I think we could incorporate some of that code in KSPCF since it's LGPL?

Also note that Solar panels have a similar problem.

Transform sync only happens if there was actually some changed transforms in between two separate engines fixedupdates, which will indeed be the case when gimbals are actively moving.

Batching the raycasts and engine damage execution at a deferred point of execution would indeed be ideal, but we should strictly limit that to stock modules, as we can't predict the behavior of modded engines (ie, SolverEngines...). Handling other modules that also perform raycasts (solar panels, radiators) would be more difficult as the core functionality of those modules is dependant on the raycasts results, so deffering execution would have even more consequences (and in the case of solar panels, there are definitely a lot of plugins either subclassing them or relying on the stock behavior).

Maybe a less intrusive solution would be to simply ensure a call to Physics.SyncTransforms is performed prior to the first raycast of any of those modules, then to disable Physics.autoSyncTransforms when the raycasts are performed.

The risk of doing that would be that if a partmodule is changing a position/rotation in between, the raycast results won't account for that change, but I fail to see any case where this could be a practical issue. There aren't many reasons to move transforms from a partmodule, and the few I can think of are small incremental moves that won't matter given the level of precision the raycasts are used for. Even if we have a partmodule moving the whole vessel, which I would expect to be a rare event, the raycasts will be accurate as far as the relative position of parts are involved. This could only matter for raycasting against the environment/terrain, and I fail to see a use case for continuously teleporting the vessel when in the vicinity of something else.

Fix implemented in #220

Released in 1.35.0