Skip to content

Creating a New Plugin on Linux in 2025

Xavier Distelzweig edited this page Apr 15, 2025 · 4 revisions

Howto: develop KSP plugins on linux

Note

This is not at all comprehensive; I'm still new to KSP modding.

Despite the facts that:

  • Visual Studio (at least to my knowledge) is uninstallable on linux (even thru wine)
  • the .NET Framework 4, which KSP uses, is fully incopatible with non-windows systems, and was designed to be so

You can still develop KSP plugins on linux! Here's how:

1: Install the necessary tools

  • I imagine you already have your favorite text editor; I use VSCode with these extensions:
    • C#
    • C# Snippets
    • C# XML Documentation Comments
    • KSP CFG Support
    • KSP CFG Language Server
    • Unity Code Snippets
    • XML (for editing .csproj files)
  • Git/Hub
  • The latest version of Mono. At the time of writing this is 6.12; run mono --version to see your Mono version. Note that this may not be the version available through your package manager.
  • The dotnet CLI. This may be available from your package manager; I got it from snap (snap install --classic dotnet-sdk). Either version 8 or 9 works.

Important

The version of the dotnet CLI you install is not and should not be 4, the version of .NET KSP uses. This will be specified in the project files for your mod later on. Installing the .NET Framework 4.8.1 will not work. But the dotnet CLI will and KSPBuildTools will fill the gap. More on that later.

2: Set up the project

  • Go ahead and create a github repository for your mod and clone it locally. Use the "Dotnet" .gitignore template; it is quite helpful though not quite comprehensive.
  • Create a solution for your mod by running dotnet new sln --name YourModNameHere in your repo root.
  • Create a source directory in your repo root for cs files and the like (I'll call it src/).
  • Create a (.cs) source file in src/ (this is just a dummy file to make sure the build process works) and put this in it:
using System;
using System.Collections.Generic;
using UnityEngine;

namespace TestMod2
{
    [KSPAddon(KSPAddon.Startup.Flight, false)]
    public class TestMod : MonoBehaviour
    {
        public void Update()
        {
            bool key = Input.GetKey(KeyCode.LeftAlt) && Input.GetKeyDown(KeyCode.Alpha1);
            if (key)
            {
                List<Part> parts = FlightGlobals.ActiveVessel.parts;
                int index;
                System.Random rnd = new System.Random();
                index = rnd.Next(1, parts.Count); //we ignore the root part by starting at 1
                parts[index].explode();
            }
        }
    }
}

(This from Linx' yt walkthru -- but I found it on HBStratos' page, a wonderful resource.)

  • then, in src/, create a file called YourModName.csproj. This is the build configuration file, and I'm gonna give it its own section because I found the docs on this file difficult to work thru. (Mostly because all the instructions assume you have VS!)

3: Create your .csproj file

Note

I'm going to explain this in detail, as a note to myself and because there's quite a bit of VS IDE generation that (can) go into this file that, without VS, has to be done manually. Feel free to skip around if you know what you're doing.

So the csproj file's job is to tell .NET how to build your project. This involves referencing all the source files, all the KSP assemblies, etc, etc. Fortunately, most of this can be automated. So, go ahead and open up that file and add this:

<?xml version="1.0" encoding="UTF-8"?>
<!-- this is what's called an "sdk-style project" -->
<Project Sdk="Microsoft.NET.Sdk">
    <!-- Since KSP uses .NET 4.8 -->
    <PropertyGroup>
        <!-- THIS is where the .NET version you'll actually use gets specified. -->
        <TargetFramework>net4.8</TargetFramework>
    </PropertyGroup>
    <!-- include KSPBuildTools - see below -->
    <ItemGroup>
        <PackageReference Include="KSPBuildTools" Version="0.0.3-alpha.4"></PackageReference>
    </ItemGroup>
</Project>

KSPBuildTools will handle referencing the KSP assemblies and a lot of other things for you.

Your .csproj file now should have everything you need to build your project. Except that we have to tell KSPBuildTools where your KSP install is, so that it can use the assemblies from it. However, the location of KSP may vary on different devs' machines, and so it is a good idea to create a .csproj.user file in the same place and with the same name as your csproj file. This should NOT be checked into git: I recommend adding a line with *.user to the end of your .gitignore. So now, in src/YourModName.csproj.user write:

<?xml version="1.0" encoding="UTF-8"?>
<Project>
    <PropertyGroup>
        <!-- this should be the DIRECTORY in which
             KSP.x86_64 resides -->
        <KSPRoot>/fully/qualified/path/to/KSP/</KSPRoot>
    </PropertyGroup>
</Project>

Tip

If you have installed KSP via steam this path may be in the hidden folder ~/.steam. KSPBuildTools can detect KSP from steam on other platforms, but not on Linux. If you're reading this and you have installed KSP via steam, please consider opening a PR on KSPBuildTools to get this added.

Now, it is finally time to...

4: Build your project

For .NET to know where your project file (.csproj) is, you have to add it to the solution via dotnet sln add src/YourModName.csproj. Then you can run dotnet build in your repo root. This should install KSPBuildTools and any other dependencies your project may have automatically, but if it does not, you can run dotnet restore to install them.

If you get any errors about msbuild not being found, make sure the latest mono is properly installed and on your PATH.

Note

While doing this you may get a warning like this: /usr/lib/mono/msbuild/Current/bin/Microsoft.Common.CurrentVersion.targets(31,3): warning MSB4011: "/home/you/path/to/repo/src/YourModName.csproj.user" cannot be imported again. It was already imported at "/home/you/.nuget/packages/kspbuildtools/0.0.3/build/KSPBuildTools.props (49,3)". This is most likely a build authoring error. This subsequent import will be ignored. [/home/you/your/repo/src/YourModName.csproj] This is harmless and can be ignored.

5: Not quite: testing out your plugin

So, you've built your plugin. Now comes the moment of truth: does it work? Well, first, it has to get inside your GameData folder so KSP can load it. While you could copy the build output over, this will quickly become tedious and you'll forget yada yada yada. So, it's far better to symlink it in, so that every time you build, KSP will automatically load your new version.

So, the build process should have created a folder called GameData in your repo and under it something like this:

GameData
└── YourModName
    ├── YourModName.dll
    └── YourModName.pdb

The YourModName directory is what you'll want to symlink to. So go ahead and open a terminal in your KSP GameData folder (NOT the one in your repo) and then run ln -s /full/path/to/your/repo/GameData/YourModName.

Tip

If you are having trouble with KSPBuildTools being able to put your built files in the right directory, you may need to set $(RepoRootPath) and/or $(BinariesOutputRelativePath) in your .csproj file like this (add right after the first <PropertyGroup/> tag):

     <PropertyGroup>
        <ModName>YourModNameHere</ModName>
        <RepoRootPath>$(MSBuildThisFileDirectory)/../</RepoRootPath>
        <BinariesOutputRelativePath>GameData/$(ModName)/</BinariesOutputRelativePath>
    </PropertyGroup>

Now, start KSP! (for load time's sake, I hope you chose an unmodded install....) Open a sandbox save, launch a stock ship and celebrate by destroying random parts on the vehicle! (That's what the example code does. Hit LeftAlt+1.)

6: Some housekeeping and other cool stuff

You've got a (hopefully) working plugin! But there's one or two other things that can make life easier for you.

The default clean process in KSPBuildTools does not affect the binaries in repo/GameData. This bothers me, and so I added this to my .csproj file, just before the KSPBuildTools import:

    <!-- Add cleanup -->
    <Target Name="CleanRepo" AfterTargets="CoreClean">
        <Delete Files="$(RepoRootPath)GameData/$(SolutionName)/$(SolutionName).dll" />
        <Delete Files="$(RepoRootPath)GameData/$(SolutionName)/$(SolutionName).pdb" />
        <Delete Files="$(RepoRootPath)GameData/$(SolutionName)/$(SolutionName).version" />
    </Target>

This simply says to .NET, whenever you clean the repo, delete these files in the repo GameData folder. To clean, run dotnet clean. Also, these files in your repo GameData are not covered by the Dotnet .gitignore, so I'd recommend adding *.dll, *.pdb and *.version to your .gitgnore.

So now you should be able to use all the cool features of KSPBuildTools, like .version file generation, mod dependency auto-installation for your project via CKAN, logging tools/helpers, and other such goodies. Highly recommend the full documentation.

Also, it is probably a good idea to add a src/Properties/AssemblyInfo.cs to your project. Though I think it may not be necessary given certain KSPBuildTools features. See their docs. This is one of those things I'm still figuring out. I just copy-pasted mine from KSPCF's and appeased the compiler when it complained (and changed the names and stuff).

Some Credits

I had a lot of help getting all this set up, especially from JonnyOThan on discord. This page is structually and conceptually based on one by HBStratos, which is phenomenal but uses VS and is on a Windows platform.