# Submodules and entry points

A [converter](/doc/converters-vL6rhSvryK) gives authors `PM:Patch("MyThing", ...)`. That works, but it is the raw form. The stock content gets nicer entry points: `PM.Parts:Patch(...)` in Lua and `Patching.Mod.PatchPart(...)` in C#, each with the converter and label filled in. This page covers adding those for your own content.

## A typed Lua submodule

To give authors `PM.MyThing:Patch(...)`, add a submodule. Mark a class with `[PatchManagerModule("MyThing")]` and `[MoonSharpUserData]`, and give it the required constructor (a `PatchManagerCore` followed by a `Universe`):

```csharp
using MoonSharp.Interpreter;
using PatchManager.LuaPatching;
using PatchManager.LuaPatching.Attributes;
using PatchManager.LuaPatching.Builtin;

[PatchManagerModule("MyThing")]
[MoonSharpUserData]
public class MyThingLuaModule
{
    private readonly PatchManagerCore _core;
    private readonly Universe _universe;

    public MyThingLuaModule(PatchManagerCore pmc, Universe universe)
    {
        _core = pmc;
        _universe = universe;
    }

    public PatchDefinition Patch(ScriptExecutionContext context, string name)
        => _core.Patch(context, "MyThing", "my_label", name);
}
```

PatchManager instantiates one of these and exposes it on the global `PM` table under the name you gave, so authors write `PM.MyThing:Patch("...")`. A method that authors call takes a `ScriptExecutionContext` as its first parameter (the scripting layer supplies it automatically) followed by the author-facing arguments. This class is exactly how `PM.Parts` is built, so the stock submodules are the reference to copy. Add whatever creation or convenience helpers your content needs as more methods.

Pass the `ScriptExecutionContext` to `_core`. `_core.Patch(context, ...)` and `_core.New(context, converter, label, name, value)` record the calling mod and the open `PM:WithFeature` scope, if there is one. This record gates the patch or asset on the [features](/doc/features-geboWdIiDN) of the author. Make each creation helper return the `LuaAsset` that `_core.New` returns. Authors can then add `:Feature` and `:NoFeature` to it. The `New` overload without a context creates an asset that no mod owns. No feature gates that asset.

## A fluent C# entry point

To let C# patch authors write `Patching.Mod.PatchMyThing("...")` instead of the generic `Patching.Build<T>`, add an extension method on `PmScope` and a `PatchAttribute` subclass that bakes your converter and label. This mirrors exactly how the parts domain ships `PatchPart` and `[PatchPart]`:

```csharp
using PatchManager.CSharpPatching;
using PatchManager.CSharpPatching.Attributes;

// The attribute, for the declarative [PMPatch] style.
public sealed class PatchMyThingAttribute : PatchAttribute
{
    public override string Converter => "MyThing";
    public override string Label => "my_label";
}

// The fluent extension, for the Patching.Mod style.
public static class MyThingPatchExtensions
{
    public static PatchBuilder<MyThingUserData> PatchMyThing(this PmScope scope, string name)
        => Patching.Build<MyThingUserData>(scope.ModId, "MyThing", "my_label", name);
}
```

With both in place, C# authors get the same two styles the stock domains offer. See [Patching from C#](/doc/patching-from-c-729VnFfTeV).

## Brand-new globals

Submodules hang off `PM`. If you need a brand-new global of your own, the way `PM` and `J` are top-level globals rather than members of something, that goes through the environment contributor mechanism instead of a submodule. It is a heavier extension point and rarely needed for content patching, but it is how the top-level globals get contributed to each patch script's environment. For content, a submodule under `PM` is almost always the right call, since it keeps everything a patch author touches under the one `PM` namespace they already know.

## The full stack

Putting the three pages together, a complete custom content module is:


1. A [converter](/doc/converters-vL6rhSvryK) (`[Converter]`) so the content can be patched at all.
2. Optionally, [module data adapters](/doc/module-data-adapters-BmhcofIRfB) for any of your own data types that benefit from typed access.
3. A submodule (`[PatchManagerModule]`) and a C# entry point (`PmScope` extension plus `PatchAttribute`) so authors get polished, converter-filled-in entry points in both languages.

That is exactly the anatomy of the stock parts module, which is the best worked example to read.