Skin Sidecar (controller sidecar from kind knobs)
Turn a skin 'kind' into the JSON your controller actually reads
- sidecar
This is a metadata node, and the honest pitch is that it exists so you don't hand-write JSON. You pick a skin kind from a fixed list of twenty, plus a map size and a seed, and you get back a JSON string describing that skin: its tint, its texture family, whether it's humanoid or creature, its UV convention, and the shader law to apply.
Downstream - in the pack's own Unity controller and material pipeline - that string is what actually decides how a character's skin looks. Tint it, set roughness, decide whether to apply triplanar detail. The node is the runtime derivation of that contract, so there's one source of truth instead of a hardcoded blob sitting next to the graph.
The kinds
Twenty of them, sorted, and a typo is refused at prompt validation rather than at queue time - a nice property of using a combo instead of a free-text field. Humanoids first: keeper, ash_nomad, villager, villager_elder, caravan_trader, amf_warden, cherusci_scrivener, marrow_raider. Then the creatures, which run from the mundane (dune_hound, moss_elk, gloom_tortoise) to the odd (amalgam_horror, bone_crane, ironvein_construct, emberwing, husk_stalker, ridge_lizard, sand_skimmer, arena_factor, meld_creature).
Each kind carries a tint triple, a texture identifier (real named skin families for the humans - young_caucasian_male, old_caucasian_male and so on - and flat_placeholder for the creatures), and a category.
What comes out
A JSON object with the kind, tint as [r, g, b], the texture and category strings, uv: "somax", the size and seed you set, and then the shader law keys: normal_strength: 0.0, smoothness: 0.18, metallic: 0.0, triplanar_density: 3.0. Keys are sorted, so two identical runs produce byte-identical strings - which is what makes it diffable and loggable.
Note the normal_strength: 0.0. That's the same "bump off" decision the pack makes elsewhere (SkinApply writes normalTexture.scale: 0.0), for the same reason: UV-path bump through projection tangents mottles the skin. The sidecar is where that law is published.
The source describes it as the twin of an estate skin_spec.sidecar, with a parity wall pinning all twenty rows equal - meaning the in-pack version and the internal version are tested to produce the same output. Same pattern as the fit rows: one contract, two doors.
Inputs and outputs
kind(defaultkeeper) - one of the twenty.size(default 512, 256–2048) - must be in the closed vocabulary of 256/512/1024/2048, same asSkinPack.seed(default 20260906, 0 to 2^31−1) - non-negative.
One output: sidecar, a STRING of JSON. Not an output node - nothing runs until something consumes it.
Install
cd /path/to/ComfyUI/custom_nodes
git clone https://github.com/JayDataEngineer/melite-poser-nodes.git
Restart, or install melite-poser-nodes from ComfyUI Manager. Pack deps (py-soma-x[anny], trimesh, xatlas) are irrelevant here - this is dict lookups and json.dumps. One of the cheapest nodes in the pack to adopt.
Where people get burned
Nothing in a stock ComfyUI graph consumes it for you. The sidecar's real reader is the pack's estate-side compose and controller; inside a plain graph you'll feed it to a text/save node so it lands on disk beside the asset. If you were expecting it to change the render, it won't - SkinPack and SkinApply do that. This is the record of intent.
kind is a closed set you may not have a body for. The kinds come from the author's game project; picking moss_elk doesn't make anything elk-shaped. It sets tint, texture family and the shader law, nothing more.
Refusals are runtime, not validation, for size and seed. The combo catches a bad kind, but 300 is a legal integer in the widget and illegal in the code:
SkinSidecar refused: size 300 not in [256, 512, 1024, 2048]
JSON consumers must tolerate a JSON string, not an object. If you're wiring it into a custom node expecting to index into a dict, parse it first - it arrives as text, with sorted keys so you can compare two runs by eyeball.
It's estate-shaped. The keys reference a controller and a UV convention (somax) that only mean something in this author's stack. Useful if you're building a similar pipeline or want a deterministic skin-descriptor to log next to your assets; not useful as general-purpose metadata for other engines.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| kind | COMBO | keeper | 20 options: amalgam_horror, amf_warden, arena_factor, ash_nomad, bone_crane, caravan_trader, +14 |
| size | INT | 512256–2048 | — |
| seed | INT | 202609060–2147483647 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| sidecar | STRING | — |