Your first mod
This mod adds a free controller based on the game's Constant part.
1. Create the project
Create a folder containing:
MyFirstMod/
MyFirstMod.csproj
Local.props
Plugin.csUse this MyFirstMod.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>disable</Nullable>
<AssemblyName>MyFirstMod</AssemblyName>
</PropertyGroup>
<Import Project="Local.props" Condition="Exists('Local.props')" />
<PropertyGroup>
<ManagedPath Condition="'$(ManagedPath)' == ''">$(GamePath)/StellarDrive_Data/Managed</ManagedPath>
<LoaderPath Condition="'$(LoaderPath)' == ''">$(GamePath)/MelonLoader/net35</LoaderPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="StellarStriderLib" Version="1.5.1" ExcludeAssets="runtime" />
<Reference Include="MelonLoader"><HintPath>$(LoaderPath)/MelonLoader.dll</HintPath><Private>false</Private></Reference>
<Reference Include="UnityEngine.CoreModule"><HintPath>$(ManagedPath)/UnityEngine.CoreModule.dll</HintPath><Private>false</Private></Reference>
<Reference Include="Ships.Interface"><HintPath>$(ManagedPath)/Ships.Interface.dll</HintPath><Private>false</Private></Reference>
<Reference Include="Ships"><HintPath>$(ManagedPath)/Ships.dll</HintPath><Private>false</Private></Reference>
<Reference Include="Items.Model"><HintPath>$(ManagedPath)/Items.Model.dll</HintPath><Private>false</Private></Reference>
<Reference Include="Research.Interface"><HintPath>$(ManagedPath)/Research.Interface.dll</HintPath><Private>false</Private></Reference>
<Reference Include="Newtonsoft.Json"><HintPath>$(ManagedPath)/Newtonsoft.Json.dll</HintPath><Private>false</Private></Reference>
</ItemGroup>
<Target Name="ValidateReferences" BeforeTargets="ResolveAssemblyReferences">
<Error Condition="!Exists('$(LoaderPath)/MelonLoader.dll')"
Text="Set GamePath or LoaderPath to your MelonLoader installation." />
<Error Condition="!Exists('$(ManagedPath)/UnityEngine.CoreModule.dll')"
Text="Set GamePath or ManagedPath to the game's managed assemblies." />
</Target>
</Project>NuGet supplies SSLib. The other references come from your game installation. ExcludeAssets="runtime" and Private=false prevent dependency DLLs from being copied to your output.
2. Set your game path
Create Local.props and set the path to your game:
<Project>
<PropertyGroup>
<GamePath>C:/Program Files (x86)/Steam/steamapps/common/StellarDrive Demo</GamePath>
</PropertyGroup>
</Project>If your installation uses different assembly locations, also set ManagedPath or LoaderPath. Keep this file out of source control.
3. Add the plugin
Use this Plugin.cs:
using System;
using MelonLoader;
using StellarStriderLib;
[assembly: MelonInfo(typeof(MyFirstMod.Plugin), "My First Mod", "1.0.0", "YourName")]
[assembly: MelonGame("CuriousOwlGames", "StellarDrive")]
[assembly: MelonAdditionalDependencies("StellarStriderLib")]
namespace MyFirstMod
{
public sealed class Plugin : MelonMod
{
public override void OnInitializeMelon()
{
var content = StriderRegistry.Create("example.firstmod", typeof(Plugin).Assembly);
content.RegisterCategory(new CategoryDefinition
{
Id = "parts",
Name = "My First Mod",
SortOrder = 100
});
content.RegisterPart(new PartDefinition
{
Id = "controller",
Name = "First Controller",
Description = "My first SSLib part, based on the native Constant.",
Donor = "Constant",
Category = "parts",
BuildingCost = Array.Empty<ItemCost>()
});
content.RegisterResearchTree(new ResearchTreeDefinition
{
Id = "technology",
Nodes = new[]
{
new ResearchNodeDefinition
{
Id = "basics",
Name = "First Mod Basics",
UnlockedParts = new[]
{
PartRef.Mod(content.Key("controller"))
}
}
}
});
MelonLogger.Msg("My First Mod content registered.");
}
}
}The plugin registers a category, a free part, and a free research unlock. The part keeps the donor's model, sockets, and input editing.
Register content once during OnInitializeMelon. Keep example.firstmod and released local IDs stable; display names can change. AllowMove defaults to false, so pickup/move is disabled while normal use still works.