Code modding guides
These guides are for mods that ship compiled C# code.
Custom Launch Locations moves a launch pad to a different body.
Subscribe to game Messages shows how to react to game events.
Transform System Guide explains the coordinate frames of the game.
For C# patches to game content, see Patching from C#.
Campaign features in a C# mod
Each campaign uses a feature set of campaign features. Each mod has a default feature, ModId:ModId. This feature is on when the mod is on in that campaign.
A mod that is off in the loaded campaign is still installed:
Its assembly loads.
The
OnPreInitialized,OnInitializedandOnPostInitializedmethods of its plugin run as usual.
For a mod that is off, Redux disables these items:
patches
content assets (see Loading assets)
campaign hooks
campaign settings
app bar buttons
Code that your mod runs directly continues to run. Examples are Harmony patches, message subscriptions and UI that your mod builds directly. Your code must check if the mod is on.
The plugin base classes GeneralMod, MonoBehaviourMod and KerbalMod supply the members for these checks.
Enabled
Enabled is true while the default feature of your mod is on in the active feature set. Check it in all code that your mod runs directly:
private void OnVesselDeltaVChanged(MessageCenterMessage message)
{
if (!Enabled)
return;
// ...
}The active feature set changes at these times:
when the game boots into the main menu
when a campaign loads
when the player goes back to the main menu
At the main menu, only Redux, Space Warp, Patch Manager and V-SwiFT are on. All other mods are off.
Loading assets
Load the Addressables assets of your mod through the SpaceWarp2.API.Loading API. Do not call Addressables directly, because the feature gate does not see those loads.
Loading.AddAddressablesLoadingActionloads a label one time, at boot. Use it for assets that all campaigns use, for example UI and icons. These assets load also when your mod is off. Assets that you keep stay in memory in all campaigns, so keep them small.Loading.AddSetLoadingActionloads a label for each feature set. Its reset clears the data each time the feature set changes. The label is content, so its assets load only while your mod is on. Use it for content data.SaveLoad.AddStepAfteradds a step after a named step of the game load, campaign load or campaign save flow.
Register loading actions in OnPreInitialized at the latest. Register a step before the step that it follows finishes. The game load flow runs one time, so for a step of that flow, register in OnPreInitialized at the latest. If the step that it follows has already finished, the game logs a warning and the step does not run.
Mod features
Put [Feature("Id")] on a bool field of your plugin class. The field then shows if that feature is on. A bare id is a feature of your mod. A qualified id, for example Ksp2Redux:Parts, is a feature of any mod. Redux writes the field each time a feature set activates.
using SpaceWarp2.API.Features;
using SpaceWarp2.API.Mods;
public class MyModPlugin : GeneralMod
{
[Feature("HardMode")]
private bool _hardMode;
}Declare the feature in one of these locations:
the
featuressection of your swinfoyour SDK Mod asset
your code, with
Patching.Mod.DefineFeature("HardMode")inOnPreInitialized
Campaign hooks
OnCampaignLoaded() runs each time a campaign that has your mod on finishes loading. This includes quickloads and reverts. OnCampaignUnloading() runs before that campaign unloads.
Set up per-campaign state in
OnCampaignLoaded().Remove that state in
OnCampaignUnloading().
Neither hook runs for a campaign that has your mod off.
public override void OnCampaignLoaded()
{
if (_hardMode)
{
// Set up hard mode for this campaign
}
}
public override void OnCampaignUnloading()
{
// Undo what OnCampaignLoaded set up
}Feature set changes
SpaceWarp2.API.Features.ActiveFeatures reads the active feature set from all code:
ActiveFeatures.Enabledgives the ids of the enabled features. It isnullbefore a feature set activates.ActiveFeatures.IsEnabled(id)examines one qualified feature id.ActiveFeatures.IsModEnabled(modId)examines if a mod is on.ActiveFeatures.Changedis anAction<IReadOnlyCollection<string>?>event. It fires after each feature set activates. At that time, all[Feature]fields andEnabledalready agree with the new feature set.
public override void OnInitialized()
{
ActiveFeatures.Changed += enabled => SWLogger.LogInfo($"{SWMetadata.Guid} enabled: {Enabled}");
}Settings
Put [ConfigFeature("Id")] or [ConfigNoFeature("Id")] next to a [ConfigValue]:
[ConfigFeature("Id")]shows the value in the settings menu only while the feature is on.[ConfigNoFeature("Id")]shows the value only while the feature is off.
All values are also hidden while your mod is off. SWMetadata.CampaignConfigFile is the per-campaign config file of your mod. Each campaign keeps its own values in this file.
Patches
C# patches, like Lua patches, need the default feature of your mod. They also accept these conditions:
.Feature(...)and.NoFeature(...)[NeedsFeature(...)]and[NoFeature(...)]in the attribute style
See Patching from C#.