NPC Helper 2/Docs

For Developers

Mod API

Register NPCs from your own SMAPI mod with NPC Helper 2's public API: get the API, register from TOML, and query registered NPCs.

Another SMAPI mod can add NPCs at run time through NPC Helper 2's public API. Use it when your NPCs are generated by code or come from your mod's own data. For a fixed set of NPCs, a content pack is simpler.

Step 1: Depend on NPC Helper 2#

In your mod's manifest.json, list NPC Helper 2 as a required dependency so SMAPI loads it first and warns players if it is missing:

json
"Dependencies": [
  { "UniqueID": "Framework.Mod.NpcHelper", "MinimumVersion": "2.4.0" }
]

Step 2: Get the API#

Add the INpcHelperApi interface to your mod (the C# SDK includes it), then request it:

csharp
var api = helper.ModRegistry.GetApi<INpcHelperApi>("Framework.Mod.NpcHelper");

Call it from GameLaunched or later. NPCs registered after the game has loaded its data are picked up because NPC Helper 2 refreshes the affected assets.

The interface#

csharp
public interface INpcHelperApi
{
    bool RegisterNpcFromToml(string name, string toml, string sourceDirectory);
    void RegisterNpc(string name, NpcDefinition data);
    bool IsNpcRegistered(string name);
    IReadOnlyList<string> GetRegisteredNpcNames();
}

Registers an NPC from TOML text.

Argument Meaning
name The NPC's name. It overrides any Name key in the text.
toml The NPC definition, in the same format as an NPC file (NPC definition). It can contain [Dialogue], [Schedule], and [Marriage] data inline.
sourceDirectory A folder with the NPC's side files, or null if there are none.

When you pass a sourceDirectory, NPC Helper 2 looks there for the side files it finds by name in any NPC folder: Dialogue.toml, Schedule.toml, and Marriage.toml, images under sprites/ and portraits/, and translations under locale/. There are no path settings in the TOML.

The method returns false and logs the reasons if the NPC is rejected. The same validation applies as for a content pack.

csharp
string toml = "Name = \"Rei\"\nDisplayName = \"Rei\"\n[Personality]\nGender = \"Female\"\n";
bool ok = api.RegisterNpcFromToml("Rei", toml, null);

If the NPC has side files, pass its folder:

csharp
string folder = Path.Combine(helper.DirectoryPath, "NPCs", "Rei");
bool ok = api.RegisterNpcFromToml("Rei", File.ReadAllText(Path.Combine(folder, "Rei.toml")), folder);

Because only strings cross the mod boundary, this works with SMAPI's API proxying without sharing any types between mods.

RegisterNpc#

Registers an NpcDefinition built in code. The definition is validated and copied, so changing it afterwards has no effect.

SMAPI can only proxy interfaces and basic types, so this works only if your mod and NPC Helper 2 share the same NpcDefinition type. Prefer RegisterNpcFromToml.

IsNpcRegistered and GetRegisteredNpcNames#

csharp
bool known = api.IsNpcRegistered("Rei");
IReadOnlyList<string> names = api.GetRegisteredNpcNames();

They report what NPC Helper 2 has registered. Names are compared without regard to case.

Behaviour to know#

  • A name that is already registered is replaced, and a warning names both sources.
  • NPCs from RegisterNpcFromToml are rebuilt when the game language changes, and a locale/ folder inside sourceDirectory is used. NPCs from RegisterNpc stay as registered.
  • Invalid names and invalid NPC content are reported and rejected. Check the return value and the SMAPI log. As with any SMAPI API call, this does not guard against unrelated errors in the calling mod.