Skip to content

Cryptoc1/lc-plugin-sdk

Repository files navigation

LethalCompany.Plugin.Sdk

NuGet Build Language

An MSBuild Sdk for creating Lethal Company mods that:

  • Optimizes Build Defaults
  • Enables Modern Language Features with PolySharp
  • References Publicized Binaries from LethalAPI.GameLibs
  • References BepInEx packages from the BepInEx Registry
  • Creates Thunderstore Packages with dotnet publish
  • Stages plugins to local a Thunderstore profile
  • And More...

Usage

To start using the Sdk, create a new Class Library:

$ dotnet new classlib -n {NAME}

In the new .csproj, update the Sdk="Microsoft.NET.Sdk" attribute at the top of the file to Sdk="LethalCompany.Plugin.Sdk/{VERSION}", and replace any existing content with metadata about the plugin:

<Project Sdk="LethalCompany.Plugin.Sdk/1.0.0">
  
  <PropertyGroup>
    <Title>Plugin Example</Title>
    <Description>My example plugin!</Description>
    <PluginId>example.plugin</PluginId>
    <Version>1.0.0</Version>
  </PropertyGroup>

</Project>

Add a new .cs file, and define the plugin:

[BepInPlugin(GeneratedPluginInfo.Identifier, GeneratedPluginInfo.Name, GeneratedPluginInfo.Version)]
public sealed class SamplePlugin : BaseUnityPlugin
{
    // ...
}

The Sdk generates a GeneratedPluginInfo class from the metadata provided in your project for usage in code.

The name of the generated class can be changed using the <PluginInfoTypeName /> MSBuild property.

By default, the generated class is internal static, this can be changed using the <PluginInfoTypeAccessModifier /> MSBuild property.

Publish to Thunderstore

In order to create a Thunderstore Package, the Sdk requires that icon.png and README.md files exist at the project root.

The location of the CHANGELOG.md and README.md files can be customized using the <PluginChangelogFile /> and <PluginReadMeFile /> MSBuild properties.

In the .csproj of the plugin, provide the metadata used to generate a manifest.json for publishing:

<Project Sdk="LethalCompany.Plugin.Sdk/1.0.0">
  
  <PropertyGroup>
    <!-- ... -->

    <Description>My example plugin!</Description>
    <ThunderId>ExamplePlugin</ThunderId>
    <ThunderWebsiteUrl>https://example.com</ThunderWebsiteUrl>
    <Version>1.0.0</Version>
  </PropertyGroup>

  <ItemGroup>
    <ThunderDependency Include="ExampleTeam-OtherPlugin-1.0.0" />
  </ItemGroup>

</Project>

The following manifest.json would be generated for the example metadata:

{
  "name": "ExamplePlugin",
  "dependencies": ["BepInEx-BepInExPack-5.4.2100", "ExampleTeam-OtherPlugin-1.0.0"],
  "description": "My example plugin!",
  "version_number": "1.0.0",
  "website_url": "https://example.com"
}

To create a Thunderstore package, use dotnet publish:

$ dotnet publish -c Release
MSBuild version 17.8.3+195e7f5a3 for .NET
  Determining projects to restore...
  All projects are up-to-date for restore.
  ExamplePlugin -> .\bin\Debug\netstandard2.1\ExamplePlugin.dll
  ExamplePlugin -> .\bin\Debug\netstandard2.1\publish\
  Zipping directory ".\bin\Debug\netstandard2.1\publish\" to ".\bin\Debug\netstandard2.1\ExamplePlugin-1.0.0.zi
  p".

Staging Plugins

"Staging" a plugin refers to the process of publishing a plugin directly to a local Thunderstore profile, and is performed by specifiying the PluginStagingProfile MSBuild property when publishing:

dotnet publish -p:PluginStagingProfile="..."

It is recommended to set the <PluginStagingProfile /> MSBuild property in a .csproj.user file.

Specify Thunderstore Dependencies

To specify Thunderstore dependencies in the generated manifest.json, use the ThunderDependency item:

<ItemGroup>
  <ThunderDependency Include="ExampleTeam-ExamplePlugin-1.0.0" />
</ItemGroup>

The Sdk specifies a default ThunderDependency on BepInExPack, specifying one yourself is unnecessary.