Create a class library project outside the Rain World installation. The project below builds a BepInEx 5 plugin against Rain World v1.11.8, Steam build 22785462. It uses the .NET Framework 4.7.2 reference assemblies through net472. This configuration compiled on Windows with .NET SDK 10.0.400, zero warnings, and zero errors. Linux and macOS compilation and in-game loading have not been tested for this example.

Create a folder, add the Plugin.cs from First plugin, and save this as MyMod.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net472</TargetFramework>
    <AssemblyName>MyMod</AssemblyName>
    <RootNamespace>MyMod</RootNamespace>
    <LangVersion>7.3</LangVersion>
    <Nullable>disable</Nullable>
    <ImplicitUsings>disable</ImplicitUsings>
    <RainWorldPath Condition="'$(RainWorldPath)' == ''">$(RAINWORLD_PATH)</RainWorldPath>
  </PropertyGroup>
 
  <Target Name="RequireRainWorldPath" BeforeTargets="ResolveReferences" Condition="'$(RainWorldPath)' == ''">
    <Error Text="Set RainWorldPath with -p:RainWorldPath=/path/to/Rain World, or set the RAINWORLD_PATH environment variable." />
  </Target>
 
  <ItemGroup>
    <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
  </ItemGroup>
 
  <ItemGroup>
    <Reference Include="BepInEx">
      <HintPath>$(RainWorldPath)/BepInEx/core/BepInEx.dll</HintPath>
      <Private>false</Private>
    </Reference>
    <Reference Include="HOOKS-Assembly-CSharp">
      <HintPath>$(RainWorldPath)/BepInEx/plugins/HOOKS-Assembly-CSharp.dll</HintPath>
      <Private>false</Private>
    </Reference>
    <Reference Include="Assembly-CSharp">
      <HintPath>$(RainWorldPath)/RainWorld_Data/Managed/Assembly-CSharp.dll</HintPath>
      <Private>false</Private>
    </Reference>
    <Reference Include="Assembly-CSharp-firstpass">
      <HintPath>$(RainWorldPath)/RainWorld_Data/Managed/Assembly-CSharp-firstpass.dll</HintPath>
      <Private>false</Private>
    </Reference>
    <Reference Include="UnityEngine">
      <HintPath>$(RainWorldPath)/RainWorld_Data/Managed/UnityEngine.dll</HintPath>
      <Private>false</Private>
    </Reference>
    <Reference Include="UnityEngine.CoreModule">
      <HintPath>$(RainWorldPath)/RainWorld_Data/Managed/UnityEngine.CoreModule.dll</HintPath>
      <Private>false</Private>
    </Reference>
    <Reference Include="UnityEngine.InputLegacyModule">
      <HintPath>$(RainWorldPath)/RainWorld_Data/Managed/UnityEngine.InputLegacyModule.dll</HintPath>
      <Private>false</Private>
    </Reference>
  </ItemGroup>
</Project>

BepInEx.dll, HOOKS-Assembly-CSharp.dll, and Assembly-CSharp.dll are the basic plugin, generated hook, and game-code references. Assembly-CSharp-firstpass.dll and the Unity references match the inspected baseline and cover types commonly reached through game code. Add another installed assembly only when the compiler names an unresolved type.

Private set to false is MSBuild’s Copy Local setting. The checked build output contains the plugin DLL and its symbols, with no BepInEx, hook, game, or Unity DLLs. The Microsoft.NETFramework.ReferenceAssemblies package supplies framework metadata for compilation, including on a machine without a Windows targeting pack. PrivateAssets="all" keeps that package dependency from flowing to projects that consume this one. It does not replace the DLL reference settings or the need to inspect your release package.

Set the game path and build

For a game installed through Steam, open Rain World’s Properties, select Installed Files, then select Browse. Use the folder containing RainWorld.exe, RainWorld_Data, and BepInEx as the game path. This project needs the installed BepInEx/plugins/HOOKS-Assembly-CSharp.dll. A standard BepInEx installation alone does not supply Rain World’s generated hook assembly. Keep the reference files from one working Rain World modding installation together.

Pass the path to dotnet build. This command uses the same .NET CLI on Windows, Linux, and macOS:

dotnet build MyMod.csproj -p:RainWorldPath="/full/path/to/Rain World"

Shell syntax for a temporary RAINWORLD_PATH value differs:

Windows PowerShell:

$env:RAINWORLD_PATH = "C:\Program Files (x86)\Steam\steamapps\common\Rain World"
dotnet build MyMod.csproj

Linux shell:

export RAINWORLD_PATH="$HOME/.local/share/Steam/steamapps/common/Rain World"
dotnet build MyMod.csproj

macOS shell, using a private copy of your Windows installation’s reference folders:

export RAINWORLD_PATH="/full/path/to/Rain World"
dotnet build MyMod.csproj

The Linux path is only an example. Steam libraries can be elsewhere. On a separate development machine, copy the referenced folders from your own game installation into a private directory, preserving the paths used by HintPath. Keep those binaries out of Git and your published mod. macOS users need access to these Windows game references even when the editor and SDK run natively.

The project is portable build input. It does not establish that Rain World, BepInEx, or a built plugin runs on that operating system. Rain World’s Steam store page lists Windows 10 64-bit for both minimum and recommended requirements. For a Windows game used through Proton or Wine, follow BepInEx’s Proton/Wine guidance for the game process and use the installed prefix’s game folder as RainWorldPath. The store page does not document native macOS support.

Edit without a Windows-only IDE

Use any editor that can edit XML and C#. BepInEx lists Rider and Visual Studio Code as cross-platform options. An editor does not replace the SDK. Check the command line first:

dotnet --list-sdks

Install a .NET SDK if this prints no SDKs. Microsoft provides installation instructions for Windows, Linux distributions, and macOS. Operating systems keeps the tool and game-process distinctions in one place.

Start from the checked example

The repository’s FirstPlugin project file uses this layout and compiles its existing Plugin.cs. From the repository root:

dotnet build examples/FirstPlugin/FirstPlugin.csproj -p:RainWorldPath="/full/path/to/Rain World"

It writes examples/FirstPlugin/bin/Debug/net472/FirstPlugin.dll. Copy that DLL into a separate local mod folder only after the build completes. First plugin covers the folder layout and the limited runtime checks that remain.

Sources