Welcome to the entry-level tutorial for modding. If you are here, you are probably wondering where to get started. This thread will go over all of the basics. How to set up a project, what tools you need, where to find information, etc. I should note this tutorial is Windows exclusive to minimize confusion.
There's a lot to cover, so let's dive on in!
Tools:
dnSpy or ILSpy - Opens DLL files.
Visual Studio - This allows you to make your own mod DLL's. Community Edition is free. Get .NET desktop development from the installer.
Github Desktop - Github is an invaluable source for making collaborations easy as well as helping to keep your mods transparent. Github Desktop helps you to easily push and pull changes to your project, however you have to use the website to make a downloadable release as well as to make a new account.
Getting Started:
Now that you have the tools you need, you can start creating. You will need to have at least a basic understanding of C#, Unity, and how to read code before you start, as you will be interacting with the game's code.
Open Visual Studio and create a new project. Change the language to C# and choose "Class Library (.NET Framework)". Check "Place project and solution in the same directory" and use .NET Framework 4.8.
Go to the "Git" tab and follow the instructions to create a new repository for your mod. Now, open Github Desktop and go to File > Add local repository > Choose...
Navigate to where you set your repositories to be saved, open the folder for your mod, then select the folder. You can now easily save your code to the repository, called committing, and pull changes made by others if you are doing a collaboration. You will want to push your code to the repository whenever you make a new release, or just periodically as you add new things. Changes will automatically be shown in the side bar, and you can chose what you want to commit.
Open Visual Studio. Right-click your project name in the side bar, then go to Add... > Reference. Navigate to your SFS Steam files, then go to Data\Managed. Select
These references allow you to use all the libraries you need and hook into the game's code.
For the mod loader to get your mod, it will need an "entry point", meaning the main class that tells the loader what to do when it loads and where to get the details of your mod such as name, version, latest supported game version, etc.
If you want to place a window with text, buttons, etc. on the screen you will need to make a new class. Here you will use the game's built-in mod GUI system.
You can create more than just a button, you can just type
Now, you will need to tell the game to show your GUI when the correct scene loads. For this example we will use the build scene.
To give your code and UI elements any functionality, you will have to use Harmony patches, which edit a method in the vanilla code. To do this, you will first need to find what you want to change within the vanilla code. Open dnSpy or ILSpy. go to File > Open, then navigate to
To edit the code, you can usually use Harmony prefixes or postfixes. These are very powerful in it of themselves, they can directly interact with the arguments that go into the method as well as change what the method outputs, and also allows you to run your own custom code before or after the method.
However, if you run into a situation where you absolutely cannot do what you are trying to do without directly editing the method's code, you will need to use a transpiler, but they are very advanced and involve manipulating raw assembly code. You should generally try to make any functions make use of prefixes and postfixes. You can also use a prefix to completely skip the method's original code and use your own custom code, but this isn't advisable as it can break compatibility with other mods.
You can find documentation about Harmony patches here.
Once you have what you'd like to change, you will need to make note of the namespace, class name, and method name. Now, make a new class for your patch.
And that's it for making your mods! To test them, you will just need to build your mod then copy it to the game's
Open Visual Studio then press Ctrl+B. It will tell you at the bottom if the build was successful.
Once you do that, open your file explorer and navigate to where you stored the repository, then go to
Each time you build a new version, you can now just overwrite the old file with the new one.
Releasing Your Mod:
Now that you've made your mod, it's time to release it publicly. Navigate to GitHub and sign in, then open your repository. Click Releases on the right, then click Draft a new release. Find your mod's folder in your game files. Drag and drop the .dll file from your file explorer to the GitHub draft. Follow the instructions to create the release, then you are done! You've now released the first version of your mod.
And that's it! This tutorial will be updated with time, as new mod loader versions come out and new tools/information surface.
Thank you for reading, and I hope this helps.
There's a lot to cover, so let's dive on in!
Tools:
dnSpy or ILSpy - Opens DLL files.
Spaceflight Simulator_Data/Managed/Assembly-CSharp.dll
is where you will find the game's compiled code. ILSpy has a much better decompiler than dnSpy, but you may find dnSpy has a more appealing interface. If you wish to use dnSpy, it's advised you still also get ILSpy in case you come upon broken-looking code and get confused. dnSpy can also directly edit the game's code without the use of Harmony patches (which will be shown later), you can use this to test changes quickly without having to build your mod every time, though it's not advised.Visual Studio - This allows you to make your own mod DLL's. Community Edition is free. Get .NET desktop development from the installer.
Github Desktop - Github is an invaluable source for making collaborations easy as well as helping to keep your mods transparent. Github Desktop helps you to easily push and pull changes to your project, however you have to use the website to make a downloadable release as well as to make a new account.
Getting Started:
Now that you have the tools you need, you can start creating. You will need to have at least a basic understanding of C#, Unity, and how to read code before you start, as you will be interacting with the game's code.
Open Visual Studio and create a new project. Change the language to C# and choose "Class Library (.NET Framework)". Check "Place project and solution in the same directory" and use .NET Framework 4.8.
Go to the "Git" tab and follow the instructions to create a new repository for your mod. Now, open Github Desktop and go to File > Add local repository > Choose...
Navigate to where you set your repositories to be saved, open the folder for your mod, then select the folder. You can now easily save your code to the repository, called committing, and pull changes made by others if you are doing a collaboration. You will want to push your code to the repository whenever you make a new release, or just periodically as you add new things. Changes will automatically be shown in the side bar, and you can chose what you want to commit.
Open Visual Studio. Right-click your project name in the side bar, then go to Add... > Reference. Navigate to your SFS Steam files, then go to Data\Managed. Select
0Harmony.dll
,Assembly-CSharp.dll
, UnityEngine.dll
, UnityEngine.UI.dll
, UnityEngine.TextRenderingModule.dll
, and UnityEngine.CoreModule.dll
.These references allow you to use all the libraries you need and hook into the game's code.
For the mod loader to get your mod, it will need an "entry point", meaning the main class that tells the loader what to do when it loads and where to get the details of your mod such as name, version, latest supported game version, etc.
C#:
using HarmonyLib;
using ModLoader;
using ModLoader.Helpers;
namespace YourProjectName
{
public class Main : Mod
{
public override string ModNameID => "ExampleID";
public override string DisplayName => "foo";
public override string Author => "bar";
public override string MinimumGameVersionNecessary => "1.5.9.8";
public override string ModVersion => "v1.0.0";
public override string Description => "Insert description here";
// This initializes the patcher. This is required if you use any Harmony patches.
static Harmony patcher;
public override void Load()
{
// This tells the loader what to run when your mod is loaded.
}
public override void Early_Load()
{
// This method runs before anything from the game is loaded. This is where you should apply your patches, as shown below.
// The patcher uses an ID formatted like a web domain.
patcher = new Harmony("example.foo.bar");
// This pulls your Harmony patches from everywhere in the namespace and applies them.
patcher.PatchAll();
}
}
}
C#:
using SFS.UI;
using SFS.UI.ModGUI;
using UnityEngine;
using Type = SFS.UI.ModGUI.Type;
namespace YourProjectName
{
public class NewClass
{
// Create a GameObject for your window to attach to.
static GameObject windowHolder;
// Random window ID to avoid conflicts with other mods.
static readonly int MainWindowID = Builder.GetRandomID();
static Window window;
static RectInt windowRect = new RectInt(0, 0, 300, 150); // x-position, y-position, width, height
/*
Call this method when you want to show your UI.
*/
public static void ShowGUI()
{
// Create the window holder, attach it to the currently active scene so it's removed when the scene changes.
windowHolder = Builder.CreateHolder(Builder.SceneToAttach.CurrentScene, "MyHolderName");
window = Builder.CreateWindow(windowHolder.transform, MainWindowID, windowRect.width, windowRect.height, windowRect.x, windowRect.y, true, true, 0.95f, "My Window");
// Create a layout group for the window. This will tell the GUI builder how it should position elements of your UI.
window.CreateLayoutGroup(Type.Vertical);
Builder.CreateButtonWithLabel(window, 290, 50, 0, 0, "Button Label", "Button Text", ButtonMethod);
}
/*
Method to pass into the button element to give it functionality
*/
static void ButtonMethod()
{
MsgDrawer.main.Log("Hello world");
}
}
}
Builder.Create
and Visual Studio's auto-fill should show you all the UI elements you can create. There are currently no docs on these, so it is advisable to look at other existing mods that make use of it for inspiration.Now, you will need to tell the game to show your GUI when the correct scene loads. For this example we will use the build scene.
C#:
public override Load()
{
/*
The below formatting is called a "lambda" method, it allows you to define a method in place of where
a pre-defined method would be accepted as a parameter. It is useful in this case because you can use it
to make it call more than one method without repeatedly adding to OnBuildSceneLoaded.
*/
SceneHelper.OnBuildSceneLoaded += () =>
{
NewClass.ShowGUI();
};
}
Spaceflight Simulator_Data\Managed\Assembly-CSharp.dll
and open it. You can now scroll through the game's source code to find what you'd like to edit, or you can use the search tool to enter various key words to try and narrow down what you want.To edit the code, you can usually use Harmony prefixes or postfixes. These are very powerful in it of themselves, they can directly interact with the arguments that go into the method as well as change what the method outputs, and also allows you to run your own custom code before or after the method.
However, if you run into a situation where you absolutely cannot do what you are trying to do without directly editing the method's code, you will need to use a transpiler, but they are very advanced and involve manipulating raw assembly code. You should generally try to make any functions make use of prefixes and postfixes. You can also use a prefix to completely skip the method's original code and use your own custom code, but this isn't advisable as it can break compatibility with other mods.
You can find documentation about Harmony patches here.
Once you have what you'd like to change, you will need to make note of the namespace, class name, and method name. Now, make a new class for your patch.
C#:
using HarmonyLib;
using UnityEngine;
using System;
// Replace SFS.Namespace with the namespace of the code you'd like to change.
using SFS.Namespace
namespace YourProjectName
{
[HarmonyPatch(typeof(OriginalClassName), "OriginalMethodName")]
public class MyPatch
{
[HarmonyPrefix]
public static (insert return type here) Prefix()
{
// Code will run before the original method.
}
[HarmonyPostfix]
public static void Postfix()
{
// Code will run after the original method. This will run regardless of if the original method or your prefix has a return.
}
}
}
Mods
folder.Open Visual Studio then press Ctrl+B. It will tell you at the bottom if the build was successful.
Once you do that, open your file explorer and navigate to where you stored the repository, then go to
Bin\Debug
and look for the .dll file with your project's name. Copy it, then navigate to the SFS mod folder. Place the mod inside. You can now use the F1 key in-game to open and close the console to see if your code throws any errors you need to fix.Each time you build a new version, you can now just overwrite the old file with the new one.
Releasing Your Mod:
Now that you've made your mod, it's time to release it publicly. Navigate to GitHub and sign in, then open your repository. Click Releases on the right, then click Draft a new release. Find your mod's folder in your game files. Drag and drop the .dll file from your file explorer to the GitHub draft. Follow the instructions to create the release, then you are done! You've now released the first version of your mod.
And that's it! This tutorial will be updated with time, as new mod loader versions come out and new tools/information surface.
Thank you for reading, and I hope this helps.
Last edited: