Skip to main content
The .csproj imports Krafs.Publicizer.2.3.0\build\Krafs.Publicizer.props and verifies it exists before the build starts. If the NuGet package has not been restored, this file is missing and MSBuild emits an error like:
error : This project references NuGet package(s) that are missing on this computer.
The missing file is ..\packages\Krafs.Publicizer.2.3.0\build\Krafs.Publicizer.props.
Solution: restore NuGet packages.From the command line:
nuget restore
Or in Visual Studio: right-click the solution in Solution Explorer and select Restore NuGet Packages.After restoring, the packages\Krafs.Publicizer.2.3.0\ directory will exist next to your solution file and the build will proceed.
MSBuild resolves all <HintPath> references through the $(ChroMapperDir) environment variable. If the variable is not set, or points to the wrong directory, the compiler cannot find Main.dll, Plugins.dll, 0Harmony.dll, or any other ChroMapper assembly.Solution:
  1. Confirm ChroMapperDir is set and points to the root of your ChroMapper installation — the folder that contains the ChroMapper.exe executable.
  2. Verify the path is correct by checking that this file exists:
    $(ChroMapperDir)\ChroMapper_Data\Managed\Main.dll
    
  3. Restart your IDE after setting or changing the variable. MSBuild reads environment variables at startup, so an already-open IDE session will not see the updated value.
To set the variable from PowerShell:
[System.Environment]::SetEnvironmentVariable(
    "ChroMapperDir",
    "C:\path\to\ChroMapper",
    "User"
)
ChroMapper loads plugins from its Plugins directory and registers every class decorated with [Plugin].Check the following:
  1. DLL was copied — confirm the post-build step ran successfully and your .dll is present in $(ChroMapperDir)\Plugins\. If the post-build xcopy failed, copy the DLL manually from bin\Debug\ or bin\Release\.
  2. [Plugin] attribute is present — the plugin entry-point class must be decorated with [Plugin(Name)]:
    [Plugin(Name)]
    public class Plugin { ... }
    
  3. Class is public — ChroMapper uses reflection to find plugin classes; a non-public class will not be found.
  4. Check ChroMapper logs — open %APPDATA%\..\LocalLow\BinaryElement\ChroMapper\Player.log (or the log path shown in ChroMapper’s settings) for error messages about plugin loading.
The post-build target runs two xcopy commands to copy the compiled output to $(ChroMapperDir)\Plugins\. If either command fails, the build reports a non-zero exit code.Common causes:
  • ChroMapperDir is not set — xcopy receives an empty path and fails. Set the variable and restart your IDE (see the entry above).
  • Plugins directory does not exist — xcopy cannot copy into a directory that doesn’t exist. Launch ChroMapper at least once so it creates the Plugins folder, or create it manually:
    New-Item -ItemType Directory -Path "$env:ChroMapperDir\Plugins"
    
  • Insufficient permissions — if ChroMapper is installed in a protected location (e.g., C:\Program Files\), xcopy may be blocked by UAC. Run your IDE as administrator, or move ChroMapper to a user-writable path.
If your [HarmonyPatch] classes compile and load without errors but the patches have no effect, work through this checklist:
  1. PatchAll is called in [Init] — confirm your Init method calls PatchAll:
    [Init]
    private void Init()
    {
        new Harmony(ID)
            .PatchAll(Assembly.GetExecutingAssembly());
    }
    
  2. Harmony ID is unique — if another loaded plugin uses the same Harmony ID, patches from both plugins are grouped together and one may override the other. Ensure your Author and Name constants produce a unique ID.
  3. [HarmonyPatch] targets the correct type and method — double-check the type and method name in your patch attribute. A typo or wrong overload silently skips the patch:
    [HarmonyPatch(typeof(SomeChroMapperClass), nameof(SomeChroMapperClass.SomeMethod))]
    class MyPatch
    {
        static void Prefix() { ... }
    }
    
  4. Patch method names are correct — Harmony recognizes Prefix, Postfix, Transpiler, and Finalizer by convention. Any other name is ignored.
This error means you are trying to access an internal or private member of a ChroMapper type that Krafs.Publicizer has not yet publicized — most often because the NuGet package is not restored.Solution:
  1. Restore NuGet packages (see the Krafs.Publicizer entry above).
  2. Confirm packages.config lists Krafs.Publicizer:
    <package id="Krafs.Publicizer" version="2.3.0" targetFramework="net48" developmentDependency="true" />
    
  3. Confirm the .csproj imports the Publicizer props and targets:
    <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 both entries are present and the package is restored but you still see CS0122, clean and rebuild the project to force Publicizer to re-process the referenced assemblies.

Build docs developers (and LLMs) love