Converters

A converter is what turns an asset's JSON into the value a patch callback edits and back again. Adding one lets patch authors patch a kind of content PatchManager does not yet cover. It is the foundation the other extension points build on.

Writing a converter

Implement IConverter and name it with [Converter("...")]:

using MoonSharp.Interpreter;
using Newtonsoft.Json.Linq;
using PatchManager.LuaPatching;
using PatchManager.LuaPatching.Attributes;

[Converter("MyThing")]
public class MyThingConverter : IConverter
{
    public DynValue FromJson(JToken json) => /* wrap json into a Lua-facing value */;
    public JToken ToJson(DynValue value) => /* serialize value back to json, or null to delete */;
}

FromJson lifts the stored JSON into the value the patch callback receives. ToJson serializes that value back after the callback runs, or returns null to signal the asset should be deleted. The class needs a parameterless constructor.

PatchManager discovers the converter by reflection at load and registers it under the name you gave. From that point a Lua patch author can use it through the generic form:

PM:Patch("MyThing", "my_label", "SomePatch"):Do(function(value) ... end)

The simplest converter just wraps the raw JSON, which is all the built-in JSON converter does. A richer converter lifts the JSON into a custom wrapper type that exposes typed helpers, which is the next piece.

Exposing types to Lua

For a value your converter returns to be useful in Lua, its type has to be visible to the scripting layer. Mark the wrapper type with [MoonSharpUserData]. That registers it so its public members are callable from Lua, with values marshalled across automatically. This is the same attribute the stock wrappers (PartUserData and friends) carry. Without it, a Lua script cannot reach your type's methods.

[MoonSharpUserData] is the bridge for every C# type you expose through any of these extension points: converter wrappers, module data adapters, and submodules all carry it.

After the converter

A converter gives authors PM:Patch("MyThing", ...) with whatever value your FromJson returns. To go further: