Skip to content

countlessbats/Ink

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Ink

Ink is a MelonLoader mod for Shin Megami Tensei III: Nocturne HD Remaster that recolors the Demi-fiend's tattoo glow.

The mod is meant to do two jobs:

  • Give players an AnyMenu setting for their default tattoo color.
  • Give other mods a small override API so temporary effects can take control of tattoo color without each mod fighting over rendering hooks.

Ink is open source under the MIT license.

Status

Ink is experimental rendering work. It has working color-selection and override plumbing, plus two rendering strategies:

  • A D3D11 constant-buffer hook that scans mapped uploads for SMT3HD's vanilla cyan tattoo color and replaces that RGB triplet.
  • A Unity material/property-block fallback that targets observed Demi-fiend tattoo materials by material and texture names.

The D3D11 path can produce high replacement counts, and the material path can affect loaded Demi-fiend materials. Combat visibility can still vary by model/material path, render timing, and what the game has already cached. See INK_NOTES.md for investigation notes and caveats.

Features

  • AnyMenu integration: Ink: Tattoos.
  • Palette entries: Default, Orange, Red, Crimson, Pink, Purple, Blue, Ice, Green, Lime, Yellow, Gold, White.
  • Default mode restores vanilla cyan and avoids D3D color mutation.
  • Public static override API for other mods.
  • Pulse override API for effects that should oscillate between two colors.
  • D3D11 hook cleanup on mod unload.

Requirements

  • SMT3 HD Remaster on Windows.
  • MelonLoader 0.6.x installed for SMT3 HD.
  • .NET 6 SDK for building.
  • MelonLoader-generated IL2CPP assemblies.
  • Optional: AnyMenu, for the in-game color setting.

Launch the game once with MelonLoader installed before building so these folders exist:

<SMT3HD>\MelonLoader\net6\
<SMT3HD>\MelonLoader\Il2CppAssemblies\

Build

From this repository:

& "C:\Program Files\dotnet\dotnet.exe" build ".\Ink.csproj" -c Release /p:GameDir="C:\Program Files (x86)\Steam\steamapps\common\smt3hd"

If your SMT3 HD install is elsewhere, replace GameDir.

The compiled DLL will be written to:

bin\Release\net6.0\Ink.dll

Install

Copy the built DLL into the game's Mods folder:

Copy-Item ".\bin\Release\net6.0\Ink.dll" "C:\Program Files (x86)\Steam\steamapps\common\smt3hd\Mods\Ink.dll" -Force

Then launch the game normally through Steam.

If AnyMenu is installed, Ink registers:

Ink: Tattoos

The caption is:

Default tattoo color.
Circumstances may override this.

Public Override API

Other mods should use Ink's API instead of writing directly to D3D11Hook.TargetR/G/B. Ink writes the active color every frame, so direct field writes can lose frame-order fights.

Ink.InkMod.SetOverride(float r, float g, float b);
Ink.InkMod.SetPulseOverride(float r, float g, float b,
                            float pulseR, float pulseG, float pulseB,
                            float speed);
Ink.InkMod.ClearOverride();
bool active = Ink.InkMod.HasOverride;

All colors are 0-1 floats.

Semantics:

  • The user's AnyMenu-selected color is the fallback.
  • Any override wins over the user's setting.
  • SetPulseOverride pulses between the first RGB color and the second RGB color.
  • speed is radians per frame; 0.08 is the default-feeling speed used during development.
  • ClearOverride() returns control to the user's selected Ink color.

Reflection Example

Use reflection if your mod should not hard-depend on Ink:

var inkType = Type.GetType("Ink.InkMod, Ink");
var setOverride = inkType?.GetMethod(
    "SetOverride",
    System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);

setOverride?.Invoke(null, new object[] { 1.0f, 0.5f, 0.0f });

Clear the override later:

var inkType = Type.GetType("Ink.InkMod, Ink");
var clearOverride = inkType?.GetMethod(
    "ClearOverride",
    System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);

clearOverride?.Invoke(null, null);

How The D3D11 Hook Works

D3D11Hook.TryAttach creates a tiny temporary Texture2D, gets its native D3D11 texture pointer, walks the device/context vtables, and attaches hooks to the immediate context's Map and Unmap.

The hook path is:

  1. Hook_Map records mapped resources by (resource pointer, subresource).
  2. Hook_Unmap scans the mapped memory before forwarding to the original Unmap.
  3. The scan looks for the vanilla tattoo cyan RGB triplet:
R = 0.003921568859368563
G = 0.9960784316062927
B = 0.8196078538894653
  1. When the triplet is found, Ink replaces it with the active target RGB.
  2. If the active color is the same vanilla cyan, Ink skips mutation.

The scan limit is currently min(rowPitch, 16384) bytes in 4-byte steps.

Material Fallback

Ink also scans loaded Unity materials and renderer property blocks at a throttled cadence. It targets a narrow observed Demi-fiend material set:

  • Material names containing body, sune, morph, kao, or shoe.
  • Texture names containing 0x00_t01, 0x00_t02, 0x00_t03, or 0x120t01 through 0x120t05.
  • _Ramp1Color values close to the vanilla cyan tattoo color.

This path exists because not every visible tattoo path is guaranteed to use the constant-buffer upload pattern Ink scans.

Modder Cautions

Do not broadly mutate every loaded renderer/material in SMT3HD. Earlier experiments with broad renderer traversal made enemies invisible.

Prefer:

  • Calling Ink's override API.
  • Keeping renderer/material changes narrowly allowlisted.
  • Saving and restoring original _Ramp1Color values.
  • Avoiding renderer.materials unless you deliberately want Unity to instantiate material copies.

Avoid:

  • Global Resources.FindObjectsOfTypeAll<Renderer>() mutation without identity checks.
  • Permanent writes to shared materials without restore logic.
  • Multiple mods installing their own D3D11 Map/Unmap hooks when Ink is present.

Source Layout

InkMod.cs       Melon lifecycle, AnyMenu registration, palette selection, override API.
D3D11Hook.cs    D3D11 Map/Unmap hook and constant-buffer RGB replacement.
TattooColors.cs Palette labels and RGB values.
INK_NOTES.md    Investigation history, combat-material findings, and future-work notes.

License

MIT. See LICENSE.

About

SMT3 HD MelonLoader mod for Demi-fiend tattoo colorization

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages