-
Notifications
You must be signed in to change notification settings - Fork 0
API Reference
For mods that register tattoos in code (procedural designs, dynamic packs, NPCs). If you just want to ship a set of PNGs, use the no-code Pack Format instead.
A complete, buildable project is in the
example repo (code-mod/).
namespace Inkorporated
{
public static class API
{
// Register from an already-loaded texture.
public static bool RegisterTattoo(
string id, string displayName, TattooPlacement placement,
UnityEngine.Texture2D texture, float price = 0f, string source = "API");
// Register from a PNG on disk (loaded lazily when first needed).
public static bool RegisterTattooFromFile(
string id, string displayName, TattooPlacement placement,
string pngPath, float price = 0f, string source = "API");
// Register from a PNG EMBEDDED in your mod's DLL - no loading boilerplate. The calling assembly is
// auto-detected; resourceName is the embedded name ("MyMod.Assets.skull.png"); "skull.png" also matches.
public static bool RegisterTattooFromResource(
string id, string displayName, TattooPlacement placement,
string resourceName, float price = 0f, string source = "API");
// ...plus an overload taking an explicit System.Reflection.Assembly if the PNG is in another assembly.
}
}
namespace Inkorporated.Model
{
public enum TattooPlacement { Chest, LeftArm, RightArm, Face }
}| Parameter | Meaning |
|---|---|
id |
Unique within your source. Used in the registered resource path. |
displayName |
The label on the shop button (falls back to id). |
placement |
Chest | LeftArm | RightArm | Face. |
texture / pngPath
|
Your tattoo image. Must match the body/face UV - see Authoring Tattoos. |
price |
Shop price; 0 shows "Free". |
source |
A stable namespace for your mod (e.g. your mod name). Used for de-duplication and the resource path. |
Returns true if added, false if it duplicated an existing (source, id).
Register early - before the tattoo shop UI is built - e.g. in your OnInitializeMelon. Tattoos
registered after that UI exists appear only the next time it is rebuilt. Registration is cheap; the actual
texture work happens lazily the first time the shop opens.
Declare Inkorporated as a hard dependency so it loads first, and reference its DLL:
[assembly: MelonAdditionalDependencies("Inkorporated")]Reference these (straight from a normal modded install - see the example's .csproj):
-
Mods/Inkorporated.dll- the API -
Mods/S1API.Il2Cpp.MelonLoader.dll- S1API (texture/NPC helpers) -
MelonLoader/net6/MelonLoader.dll,Il2CppInterop.Runtime.dll -
MelonLoader/Il2CppAssemblies/UnityEngine.CoreModule.dll,Il2Cppmscorlib.dll,Il2CppSystem.dll - For Thunderstore, list
DooDesch-Inkorporatedas a dependency.
S1API ships helpers (recommended over hand-rolling):
using S1API.Rendering;
Texture2D t1 = TextureUtils.LoadTextureFromFile(path); // from disk
Texture2D t2 = TextureUtils.LoadTextureFromBytes(pngBytes); // from bytes (e.g. an embedded PNG)Tip: if your PNG is embedded in your own DLL, skip this entirely and use
API.RegisterTattooFromResource(id, name, placement, "MyMod.Assets.skull.png", source: "MyMod") - it loads
the embedded resource for you (the calling assembly is auto-detected).
using Inkorporated;
using Inkorporated.Model;
using S1API.Rendering;
using MelonLoader;
using UnityEngine;
[assembly: MelonAdditionalDependencies("Inkorporated")]
public sealed class Core : MelonMod
{
public override void OnInitializeMelon()
{
Texture2D tex = TextureUtils.LoadTextureFromFile(@"C:\path\to\skull.png");
API.RegisterTattoo("skull", "Skull", TattooPlacement.Chest, tex, price: 0f, source: "MyMod");
}
}Each tattoo is registered at:
Avatar/Layers/Tattoos/custom/<segment>/<Source>_<Id>
where <segment> is Face for face tattoos (capitalised, so the game routes them to the face mesh) or the
lowercase placement (chest / leftarm / rightarm) otherwise. Source and Id have non-alphanumeric
characters replaced with _. You need this path only if you want to put the tattoo on an NPC - see
Multiplayer Saves and NPCs.