This guide applies only to KSP 1.8 and latter. It covers modifying a KSP installation to allow :
- In IDE debugging of KSP plugins by using breakpoints, inspecting runtime variables, doing step-by-step execution, etc. Both Visual Studio (including VS for Mac) and JetBrains Rider support debugging Unity games, and by extension KSP plugins.
- Using the Unity editor profiling tools, which include great tools to measure and analyze CPU/GPU usage and memory allocations.
This guide is extensively tested for a Windows / Visual Studio scenario. However, it is theoretically possible to make all that work under MacOS or Linux, either with the Rider IDE or Visual Studio for Mac. This guide has limited details about those scenarios. I encourage you to leave a comment if you have additional information / experience.
You will need to replace some of KSP files by those provided in the Unity editor. Beside for getting those files, you need the Unity editor if you want to use the Unity profiler :
- For KSP 1.8 to 1.11, you need Unity 2019.2.2f1
- For KSP 1.12, you need Unity 2019.4.18f1
The provided links should get you to the download page. If they don't work, find them on the Unity download archive.
Alternatively, if you only want to enable debugging, here are direct downloads to the files you need to replace in KSP :
- KSP 1.12 (Windows)
- KSP 1.12 (Linux)
- KSP 1.12 (MacOS)
- KSP 1.8 to 1.11 (Windows)
- KSP 1.8 to 1.11 (MacOS)
Before you begin, it is highly recommended to make a separate copy of a clean install of KSP for this. Just copy the whole KSP folder somewhere else.
- Open the folder where you installed the Unity editor
- Navigate to the
Editor\Data\PlaybackEngines\windowsstandalonesupport\Variations\win64_development_mono
folder - Copy the
UnityPlayer.dll
andWinPixEventRuntime.dll
files from thewin64_development_mono
folder to the KSP root folder (the one containingKSP_x64.exe
). Backup the original files elsewhere if you want to revert that installation to a non-dev build latter. - From your KSP root folder, open the
KSP_x64_Data
folder - In that folder, open the
boot.config
file with a text editor - Add the following line :
player-connection-debug=1
and save the modifications - Launch KSP
- The Windows firewall may ask you to authorize KSP to communicate on your network. You must allow it. If you previously launched KSP from that install and denied that authorization, you need to go into the Windows firewall settings and authorize it.
- Open the folder where you installed the Unity editor
- Navigate to the
Editor\Data\PlaybackEngines\LinuxStandaloneSupport\Variations\linux64_withgfx_development_mono
folder - Copy the
UnityPlayer.so
andUnityPlayer_s.debug
files from thelinux64_withgfx_development_mono
folder to the KSP root folder (the one containingKSP.x86_64
). Backup the original files elsewhere if you want to revert that installation to a non-dev build latter. - From your KSP root folder, open the
KSP_Data
folder - In that folder, open the
boot.config
file with a text editor - Add the following line :
player-connection-debug=1
and save the modifications
- Open the folder where you installed the Unity editor
- Navigate to the
Editor\Data\PlaybackEngines\MacStandaloneSupport\Variations\macosx64_development_mono\UnityPlayer.app\Contents\Frameworks
folder, locate theUnityPlayer.dylib
file. - Open the root folder of your KSP install, and navigate to the
KSP.app\Contents\Frameworks
folder (you need to right-click onKSP.app
and selectShow Package Contents
to be able to browse it). - Replace the
UnityPlayer.dylib
file of your KSP install by the Unity one. - From the Unity editor root, navigate to
Editor\Data\PlaybackEngines\MacStandaloneSupport\Variations\macosx64_development_mono\UnityPlayer.app\Contents\MacOS
and locate theUnityPlayer
file. - From the root KSP folder, navigate to your
KSP.app\Contents\MacOS
folder and locate theKSP
file. - Delete the original
KSP
file, copy theUnityPlayer
file there and rename it toKSP
. - From the root KSP folder, navigate to your
KSP.app\Contents\Resources\Data
folder. - Open the
boot.config
file with a text editor. - Add the following line :
player-connection-debug=1
and save the modifications
- Install the Visual Studio Tools for Unity extension (available from the VS installer or from the VS extension menu in older VS versions).
- In Visual Studio, open your plugin project
- From the solution explorer panel, right-click on the project and select
Properties
- In the project properties window, make sure you're under the "Debug" configuration, then go to the "Build" tab
- Click on the "Advanced" button
- In the popup window, there is a "Debugging information" dropdown : select the "Portable" option
This is an alternative to the above Visual Studio GUI based instructions :
- Open your
*.csproj
project file in a text editor - Locate the following section :
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- Under that section (make sure it's the right one, there is a similar one for the
Release
configuration), set theDebugType
property toportable
:
<DebugType>portable</DebugType>
When building your plugin assembly in the Debug
configuration, a *.pdb
debug symbols file will be generated alongside your *.dll
file. You need to copy that file alongside the dll in the GameData subfolder of your plugin.
- In Visual Studio, from the
Debug
menu, selectAttach Unity Debugger
: - In the popup, select your running KSP instance (it can sometimes take a while for it to appear) :
- Visual Studio will switch to the debugging context and you can now set a breakpoint in your code. It might say "The breakpoint will not currently be hit" initially, but that should change once your class is actually instantiated and the code executed.
- Depending on your Rider version, you might need to download the "Unity tools" extension.
- From the Rider menu, select Run > Attach to Unity Process
If the running KSP instance isn't listed in the Select Unity instance
popup :
- Make sure you followed the Modifying your game for profiling/debugging instructions correctly.
- In the KSP main menu settings, make sure you have the
Simulate In Background
option checked. - The Unity executable communicate with the debugger/profiler over a network interface, so :
- Make sure both KSP and your IDE aren't firewalled (by the Windows firewall or an antivirus/firewall software if you have one).
- Uncommon network setups like a VPN or a network bridge will often interfere. If you have multiple network interfaces (ex : ethernet + wifi), keep only one enabled.
As a last resort, you can try inputting the IP/port manually. Launch KSP and open the Player.log
file (on windows it will be here : %USERPROFILE%\AppData\LocalLow\Squad\Kerbal Space Program\Player.log
).
You need to find the IP adress and port Unity is listening on. They should be on two separate lines near the beginning of the file :
Multi-casting "[IP] 192.168.1.81
(truncated) : IP adress to useStarting managed debugger on port 56061
: port to use
Then in the Select Unity instance
popup, click on the "Input IP" button and try using the above IP/port.
See also the troubleshooting debugging Unity players page from the Rider documentation (this has useful additional information, especially for MacOS).
The Unity profiler is a frame based profiler that allow to see all calls to the default MonoBehaviour message methods (Update, FixedUpdate, etc), and to profile arbitrary sections of your code. You can measure call count, time taken and see call hierarchy and managed memory usage. See the Profiler Window documentation.
- Launch KSP
- Launch the Unity editor, and create/open a blank project
- From the editor menu, go to Window > Analysis > Profiler
- At the top of the profiler window, you should see a dropdown list where you can connect to you KSP instance. If that doesn't work, read the above Troubleshooting section.
By default, the profiler will only show calls to the message type MonoBehaviour methods, which isn't very helpful for profiling KSP plugins. To profile specific parts of your code, you need to compile your plugin with the ENABLE_PROFILER
compilation constant :
Right click your project in the solution explorer panel, select the Properties
option.
Make sure the Debug
configuration is selected, then in the Build
tab add ENABLE_PROFILER
in the Conditional compilation symbols
box. Note that if there is already a value there, you should separate additional values with a semicolon (;
).
This is an alternative to the above Visual Studio GUI based instructions :
- Open your
*.csproj
project file in a text editor - Locate the following section :
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- Under that section (make sure it's the right one, there is a similar one for the
Release
configuration), appendENABLE_PROFILER
separated with a semicolon (;
) to theDefineConstants
property :
<DefineConstants>DEBUG;TRACE;ENABLE_PROFILER</DefineConstants>
To profile an arbitrary section of your code, enclose that code between a Profiler.BeginSample("NameShownInTheProfiler")
and Profiler.EndSample()
call. See the Profiler class documentation.
For this to work reliably, you must ensure that Profiler.EndSample()
is called before every return point of your method.
The Profiler
calls are executing only if your plugin is compiled with the ENABLE_PROFILER
constant, so you can leave them around, they won't do anything and won't cause a performance overhead once you plugin is compiled in the Release
configuration.
Note that ideally, you want to do performance profiling in the Release
configuration to get a more accurate picture (debug builds are quite noticeably slower). To achieve that, you can create a third build configuration in your project (based on the Release
configuration), but with the ENABLE_PROFILER
constant added.
Note that the Profiler.*Sample()
methods have a small overhead which is insignifant in usual cases, but if you want to profile "hot paths" (small blocks of code executed many times in a loop for example) or to nest profiler calls, it is preferable to use the ProfilerMarker methods. Also note that contrary to the legacy Profiler
methods, ProfilerMarker
allow profiling Jobs
based code.
While the frame profiler is a handy and straightforward tool for fixing obvious performance issues, it doesn't give you a full picture since there will be quite some variance from one frame to another, which can be very misleading when trying to compare results from previous runs.
To get more reliable results, you can use the profile analyzer, which does advanced statistical analysis of profiling sessions, as well as saving and comparing different session results.
The profile analyzer is available as an additional Unity package. To install it, open the empty unity editor project you're using for profiling, go to the Window > Package manager
menu option, and install it. It should then appear in the Window > Analysis > Profile Analyzer
menu.
In a modified for debugging/profiling install, performance will be vastly degraded compared to an untouched KSP :
- There is a lot of extra debugging/error checking code executed on the native side of Unity, so internal Unity methods will execute slower, affecting almost every aspect of the engine (physics, rendering, game logic...).
- The Mono runtime will run with many JIT compiler optimizations disabled. This will induce a very variable and sometimes quite significant performance impact on the C# code from KSP and plugins.
- Remember that building code in the
Debug
configuration will a induce a large and variable performance penalty. To avoid that, use the same build parameters as forRelease
, but with theENABLE_PROFILER
constant added. - Attaching the profiler will cause a large overhead to your frame time.
For these reasons, profiler results should be taken with a grain of salt. The performance difference between profiler results and a regular KSP install isn't uniform : some pieces of code will run hugely slower, other won't be affected much. The profiler is still very useful to get an overall picture, comparing different implementations and identifying bottlenecks as well as GC pressure issues, but it isn't reliable at all for micro-optimization.
To perform entirely reliable performance measurements, it is necessary to implement them manually in your plugin (for example with a StopWatch
), and to run the plugin compiled in the Release
configuration in a non-modified KSP install.