Skip to main content
ChroMapper discovers and loads plugins through a small set of custom attributes. The template wires these up for you automatically; this page explains what each attribute does and how they fit together.
The [Plugin] and [Init] attributes are defined in Plugins.dll, which ships with ChroMapper and is located at $(ChroMapperDir)\ChroMapper_Data\Managed\Plugins.dll. Your project references this assembly via the ChroMapperDir environment variable.

Complete Plugin.cs reference

The template generates the following entry-point file:
Plugin.cs
using System.Reflection;
using UnityEngine;
using HarmonyLib;

namespace ChroMapperPluginTemplate;

[Plugin(Name)]
public class Plugin
{
    public const string Author = "YourName";
    public const string Name = "ChroMapperPluginTemplate";
    public const string ID = $"com.{Author}.{Name}";

    [Init]
    private void Init()
    {
        new Harmony(ID)
            .PatchAll(Assembly.GetExecutingAssembly());
        
        Debug.Log($"Hello from {Name}!");
    }
}

Attributes

[Plugin(Name)]

Marks a class as the plugin entry point. ChroMapper scans loaded assemblies for classes decorated with this attribute and registers them as plugins. The single argument is the plugin display name — the string that appears in ChroMapper’s plugin list. In the template this is the Name constant, so it always matches the project name after substitution.
[Plugin(Name)]       // Name = "ChroMapperPluginTemplate" (or your project name)
public class Plugin
{
    public const string Name = "ChroMapperPluginTemplate";
}
The class must be public.

[Init]

Marks the method ChroMapper calls immediately after loading the plugin. Place your one-time startup logic here: initializing Harmony, registering event handlers, or logging a startup message.
[Init]
private void Init()
{
    // Called once when ChroMapper loads your plugin
}
The method can be private. ChroMapper invokes it via reflection.

Plugin.ID convention

The ID constant follows the reverse-domain convention com.{Author}.{Name}:
public const string Author = "YourName";
public const string Name = "ChroMapperPluginTemplate";
public const string ID = $"com.{Author}.{Name}";
// Result: "com.YourName.ChroMapperPluginTemplate"
This string is used as the Harmony instance identifier, which namespaces all patches your plugin applies. Using a unique ID prevents conflicts with patches from other plugins.
If two plugins share the same Harmony ID, their patches can interfere with each other. Always set a unique Author and Name when you scaffold your plugin.

Harmony integration

new Harmony(ID)

Creates a Harmony instance scoped to your plugin’s ID. All patches registered through this instance are grouped under that ID, making them easy to un-patch selectively if needed.

.PatchAll(Assembly.GetExecutingAssembly())

Scans your entire assembly for classes annotated with [HarmonyPatch] and applies all the patches it finds. You do not need to list individual patch classes — Harmony discovers them automatically.
[Init]
private void Init()
{
    new Harmony(ID)
        .PatchAll(Assembly.GetExecutingAssembly());
}

Logging

Debug.Log is from UnityEngine.CoreModule. ChroMapper runs on Unity, so Unity’s logging pipeline is available. Log output appears in the ChroMapper console and in Player.log.
Debug.Log($"Hello from {Name}!");
Use Debug.LogWarning and Debug.LogError for higher-severity messages.

AssemblyInfo.cs

The template includes a Properties/AssemblyInfo.cs file with standard .NET assembly metadata attributes:
Properties/AssemblyInfo.cs
using System.Reflection;
using System.Runtime.InteropServices;

[assembly: AssemblyTitle("ChroMapperPluginTemplate")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ChroMapperPluginTemplate")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

[assembly: ComVisible(false)]

[assembly: Guid("35E8370F-DC32-473E-9185-FF618F38C4C1")]

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
AssemblyVersion and AssemblyFileVersion are the values you increment when you release a new version of your plugin. See Configuration for details on updating them.

Build docs developers (and LLMs) love