Skip to content

DEV BLOG

Early URP Port Devlog

I thought I’d make a short devlog to show off what I’ve been working on the past couple of days.

To give a bit of context, KSP2 uses the Built-in Render Pipeline. In Unity, a render pipeline is the sequence of GPU steps (culling, batching, lighting, shading, post-processing, …) that turns scene data into pixels each frame. The original, old Built-in Render Pipeline is a hardcoded implementation of that sequence, where you can tweak the parameters, but not really the logic itself. Meanwhile, the newer Scriptable Render Pipeline (which is an umbrella term for both the Universal Render Pipeline and the High Definition Render Pipeline) exposes that logic in C#, so that you can define exactly how objects are drawn, how lighting is evaluated, how render passes are structured, etc.

Now, the issue is that the BRP is going to be deprecated in Unity 6.5, and completely removed possibly as early as Unity 6.8, which coincidentally is also the stable release of CoreCLR support (which we really, really, really want for the potential crazy performance boost and the access to modern C#). Generally, we also want to be able to keep upgrading the game and not be hard stuck on a specific Unity version.

So, in order to solve this issue, we’ll need to eventually port the game from BRP to URP or HDRP. While HDRP would make the most sense with its current feature set compared to URP, Unity just recently announced that it will no longer be developed, and that URP will eventually receive all of its features and become the single recommended pipeline to use. That means that for future use, it makes more sense to start with URP right away, rather than have to go through another port in a couple of months/years.

In our case, porting from BRP to SRP is not an easy task though, arguably much more difficult than our big upgrade from Unity 2022.3 to Unity 6.3 (and now 6.4 in development). That’s because we don’t have access to the source code of the game’s shaders, and shaders are often very particular about which render pipeline they work on. That said, there are some ways (dark magic) to “hack” around this and get stuff to render using these normally incompatible shaders, and the video in this post is a look at the first “playable” version of the very early and experimental URP port of the game. Many things are still missing, but it’s honestly been going much better than I expected, so I’m feeling positive about this little side-quest that I’m on!

Chipping Away at Map View Performance Issues

Chipping away at map view performance issues

Most of the speedups in Redux focus on the simulation and main UI. We haven’t really done much to try to improve the map situation. After all, the simulation has to run at time as the map being open, so any improvement in the simulation should imply a performance improvement in the map. However, with the sim performance getting better, the FPS drop when opening the map is getting increasingly noticeable. One piece of code in particular, called RelativeOrbitSolver jumped out at me as actually getting worse due to some changes in the way transforms are handled. The current version in redux takes up a whopping 4ms on my test setup.

RelativeOrbitSolver is used for predicting future locations in a hypothetical future orbit, and calculate where those points would be with respect to some given viewer. It’s used by the map to do things like draw projected intercept lines.

For example, let’s say a vessel in orbit of Kerbol is not currently intercepting Moho. The player adds a maneuver plan that would cause it to intercept Moho’s SOI but transit through it. So, the map has to draw a bunch of different lines.

  • The current orbit line.
  • The line starting at where the maneuver node is showing the change in Kerbol orbit as a result of the planned impulse. Ends at the predicted Moho SOI intercept.
  • A line near wherever Moho currently is that shows the vessel’s predicted transit through Moho’s SOI (relative to Moho). This is technically a hyperbolic trajectory (“orbit”) of Moho.
  • Another line relative to Kerbol that shows what the previous line actually like from Kerbol’s perspective. This is the one that uses RelativeOrbitSolver.
  • A line after the projected SOI ejection that shows yet another orbit of Kerbol, but this one having been modified by Moho’s gravitational pull.

The code uses several strategies depending on what kind of line it’s drawing, but the 2nd to last one here is the one that uses RelativeOrbitSolver. It’s also used for some other tasks, such as trying to find SOI transition points.

The code for RelativeOrbitSolver is one of the few things got somewhat slower after switching to ECS frames. It created a bunch of temporary TransformModels, would move them around, and then use them for doing relative position calculations. The individual point calculations were probably faster, however the setup/teardown of the temporary frames were quite expensive. Unfortunately, a few spots in the code (such as maneuver nodes) would create a RelativeOrbitSolver to solve for exactly one point and throw it away.

So, I rewrote the code to avoid using TransformModel. While I was in there, I noticed a bug where it would ignore a celestial body’s axialTilt, which caused some issues with the line related to Moho. Now the code just scrapes the spatial relationships into a simple temporary list, and runs a simple loop to do the same calculations the more complicated transform system would do.

Map view performance 1

Map view performance 2

Map view performance 3