Skip to main content

ChroMapperDir environment variable

Every <HintPath> in the generated .csproj resolves through the ChroMapperDir environment variable. You must set this variable to the root directory of your ChroMapper installation before opening the project in your IDE or running a build.

Path pattern

$(ChroMapperDir)\ChroMapper_Data\Managed\<dll>
For example:
<Reference Include="Main">
    <HintPath>$(ChroMapperDir)\ChroMapper_Data\Managed\Main.dll</HintPath>
</Reference>
<Reference Include="Plugins">
    <HintPath>$(ChroMapperDir)\ChroMapper_Data\Managed\Plugins.dll</HintPath>
</Reference>
<Reference Include="0Harmony">
    <HintPath>$(ChroMapperDir)\ChroMapper_Data\Managed\0Harmony.dll</HintPath>
</Reference>

How to set it on Windows

System Environment Variables (persistent, all sessions):
  1. Open Start, search for “Edit the system environment variables”, and open it.
  2. Click Environment Variables….
  3. Under User variables, click New.
  4. Set Variable name to ChroMapperDir and Variable value to the full path of your ChroMapper folder (e.g., C:\Program Files (x86)\Steam\steamapps\common\ChroMapper).
  5. Click OK on all dialogs.
  6. Restart your IDE so it picks up the new variable.
PowerShell (persistent user variable):
[System.Environment]::SetEnvironmentVariable(
    "ChroMapperDir",
    "C:\path\to\ChroMapper",
    "User"
)
PowerShell (current session only):
$env:ChroMapperDir = "C:\path\to\ChroMapper"
After setting a persistent environment variable, restart your IDE. MSBuild reads environment variables at startup; an open IDE session will not see the new value.

Build configurations

The project ships with two standard MSBuild configurations.

Debug

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
</PropertyGroup>
  • Emits a full .pdb file alongside the .dll.
  • Disables optimizations so stack traces and debugger stepping reflect your source.
  • Defines both DEBUG and TRACE constants so #if DEBUG blocks are included.
  • The post-build step copies the .pdb to $(ChroMapperDir)\Plugins\ in addition to the .dll.

Release

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
</PropertyGroup>
  • Enables optimizations.
  • Produces a minimal pdbonly symbols file (not copied to ChroMapper).
  • Only the TRACE constant is defined.
SettingDebugRelease
DebugSymbolstrue
DebugTypefullpdbonly
Optimizefalsetrue
OutputPathbin\Debug\bin\Release\
.pdb copied to pluginsYesNo
DefineConstantsDEBUG;TRACETRACE

Post-build step

After every successful build the project runs an xcopy command that copies your compiled .dll directly into ChroMapper’s Plugins directory so you can launch ChroMapper immediately without a manual copy step.
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Exec Command="xcopy /Y /F &quot;$(ProjectDir)bin\$(Configuration)\$(TargetName).dll&quot; &quot;$(ChroMapperDir)\Plugins\&quot;" />
    <Exec Condition=" '$(Configuration)' == 'Debug' " Command="xcopy /Y /F &quot;$(ProjectDir)bin\$(Configuration)\$(TargetName).pdb&quot; &quot;$(ChroMapperDir)\Plugins\&quot;" />
</Target>
  • /Y — suppresses the overwrite confirmation prompt.
  • /F — prints the full source and destination file names during the copy.
  • The .pdb copy only runs in the Debug configuration.
The Plugins directory ($(ChroMapperDir)\Plugins\) must already exist. ChroMapper creates it on first launch, so run ChroMapper at least once before building your plugin.

AssemblyInfo.cs version attributes

Update AssemblyVersion and AssemblyFileVersion in Properties/AssemblyInfo.cs when you release a new version of your plugin:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
  • AssemblyVersion — used by the .NET runtime for binding. Increment the major or minor component for breaking changes.
  • AssemblyFileVersion — displayed in Windows file properties. Increment this with every release.
Both follow the Major.Minor.Build.Revision format. A typical release workflow increments Minor for new features and Build for patches:
[assembly: AssemblyVersion("1.2.0.0")]
[assembly: AssemblyFileVersion("1.2.0.0")]

packages.config and Krafs.Publicizer

packages.config
<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Krafs.Publicizer" version="2.3.0" targetFramework="net48" developmentDependency="true" />
</packages>
Krafs.Publicizer is a NuGet build-time tool that rewrites internal and private members of referenced assemblies to public before the C# compiler sees them. ChroMapper’s assemblies contain many internal types and members that plugins need to call; Publicizer removes that restriction without modifying the actual ChroMapper DLLs on disk. It is declared as developmentDependency="true", which means it is a build tool only and is not copied into your output or distributed with your plugin. The .csproj imports Publicizer’s MSBuild props and targets, and verifies they exist before the build starts:
<Import Project="..\packages\Krafs.Publicizer.2.3.0\build\Krafs.Publicizer.props"
        Condition="Exists('..\packages\Krafs.Publicizer.2.3.0\build\Krafs.Publicizer.props')" />
...
<Import Project="..\packages\Krafs.Publicizer.2.3.0\build\Krafs.Publicizer.targets"
        Condition="Exists('..\packages\Krafs.Publicizer.2.3.0\build\Krafs.Publicizer.targets')" />
If the package is not restored, the build fails with an explicit error message pointing to the missing file. Run NuGet restore to fix it (see Troubleshooting).

Build docs developers (and LLMs) love