๐ Kisekae Head
Change the expression, keep the face
- char
- char
Here's the thing that makes a character pipeline fall apart: you've got a face you like, and now you want the same face smug instead of smile. In a plain prompt you're editing one comma-separated string and hoping you don't knock out heterochromia by accident. There's no such thing as "change just this field" in a text box.
๐ Kisekae Head is that missing granularity. It's the head section of a Kisekae character - face, eyes, eyebrows, ears, mouth, expression, makeup, eyewear, accessories - and it lets you change one of those without touching the other nine.
How it works
The character is a dict passed on a KISEKAE_CHAR wire, one entry per section, each field carrying a value plus the node that set it. Head nodes can be chained, and the last one to touch a field wins.
Order of operations on every section node: the incoming character arrives, then the node's own preset pick replaces the whole head section if set (LoRAs included), then per-field overrides apply. Overrides beat everything, including that node's own preset.
Then there's the rendering trick that matters for head specifically. In Kisekae Prompt, {head} prints every head field in schema order - unless the template also names a field explicitly. The default anima-mixed template ends with {scene}, {head.expression}, so expression is printed once, at the end of the prompt, and pulled out of {head} so it doesn't appear twice. That's why the default layout puts the mood last instead of buried in the middle of the face block.
The inputs that matter
Eleven dropdowns: face, eyes, eyebrows, ears, mouth, expression, makeup, eyewear, accessories, and a multiline extra. Each has (keep), (clear) and its shipped values, and each has an advanced _text override plus an _append toggle.
For most people the three that earn their keep are eyes, expression and accessories. eyes is the identity anchor - 20-odd booru colours - and it's the field a scene preset should never stomp on. expression is the one you'll flip constantly, which is exactly why a scene preset applied in merge mode can set head.expression while leaving the rest of the head alone. accessories (choker, halo, horns, mask) drifts between "head" and "outfit" in your head; here it's head.
ears covers animal and elf ears - cat ears, fox ears, elf ears, earrings. Tails and wings do not live here; they're in Kisekae Body's extras. Getting that wrong is the classic first-hour confusion with this pack.
The preset dropdown lists only presets that define a head section. Output is a lone char - wire it to another section node or to Kisekae Prompt.
Install
ComfyUI Manager, search the pack title kisekae, or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/Kagejitsu/comfyui-kisekae
Restart. The pack declares no Python dependencies, so there's no pip install step and nothing to break on the next ComfyUI update. Nodes appear under kisekae, named "๐ Kisekae โฆ".
Common issues
Two head nodes and the earlier one seems ignored. Section nodes replace whole sections when a preset is picked on them. If your second head node loads examples/characters/aoi as its preset, it resets eyes, mouth and everything else, then applies its own overrides. Use the preset on the first head node, or use Load Preset with mode: merge.
A negative tag never shows up. Per-field negatives (short hair for a long hair pick) only travel with dropdown picks. Typed text and preset values are never pruned and never add companion negatives.
(glasses:1.2) came out weird. Brackets inside a tag get escaped by the Prompt node - menacing (jojo) becomes menacing \(jojo\) - but real weights like (tag:1.2) are preserved. If you want to see exactly what happened, drop a Kisekae Debug Prompt after this node.
Dropdown values you want are missing. Add them on Tansu's Dropdowns page, then press R in ComfyUI to refresh the node dropdowns.
Inputs (32)
| Name | Type | Default | Description |
|---|---|---|---|
| preset | COMBO | (none) | Replace the whole head section with this preset's head |
| face | COMBO | (keep) | (keep) passes the incoming value through; (clear) empties it |
| face_text | STRING | Typed text wins over the dropdown. (tag:1.2) weights work. | |
| face_append | BOOLEAN | false | append: add to the incoming value; replace: overwrite it |
| eyes | COMBO | (keep) | (keep) passes the incoming value through; (clear) empties it |
| eyes_text | STRING | Typed text wins over the dropdown. (tag:1.2) weights work. | |
| eyes_append | BOOLEAN | false | append: add to the incoming value; replace: overwrite it |
| eyebrows | COMBO | (keep) | (keep) passes the incoming value through; (clear) empties it |
| eyebrows_text | STRING | Typed text wins over the dropdown. (tag:1.2) weights work. | |
| eyebrows_append | BOOLEAN | false | append: add to the incoming value; replace: overwrite it |
| ears | COMBO | (keep) | (keep) passes the incoming value through; (clear) empties it |
| ears_text | STRING | Typed text wins over the dropdown. (tag:1.2) weights work. | |
| ears_append | BOOLEAN | false | append: add to the incoming value; replace: overwrite it |
| mouth | COMBO | (keep) | (keep) passes the incoming value through; (clear) empties it |
| mouth_text | STRING | Typed text wins over the dropdown. (tag:1.2) weights work. | |
| mouth_append | BOOLEAN | false | append: add to the incoming value; replace: overwrite it |
| expression | COMBO | (keep) | (keep) passes the incoming value through; (clear) empties it |
| expression_text | STRING | Typed text wins over the dropdown. (tag:1.2) weights work. | |
| expression_append | BOOLEAN | false | append: add to the incoming value; replace: overwrite it |
| makeup | COMBO | (keep) | (keep) passes the incoming value through; (clear) empties it |
| makeup_text | STRING | Typed text wins over the dropdown. (tag:1.2) weights work. | |
| makeup_append | BOOLEAN | false | append: add to the incoming value; replace: overwrite it |
| eyewear | COMBO | (keep) | (keep) passes the incoming value through; (clear) empties it |
| eyewear_text | STRING | Typed text wins over the dropdown. (tag:1.2) weights work. | |
| eyewear_append | BOOLEAN | false | append: add to the incoming value; replace: overwrite it |
| accessories | COMBO | (keep) | (keep) passes the incoming value through; (clear) empties it |
| accessories_text | STRING | Typed text wins over the dropdown. (tag:1.2) weights work. | |
| accessories_append | BOOLEAN | false | append: add to the incoming value; replace: overwrite it |
| extra | COMBO | (keep) | (keep) passes the incoming value through; (clear) empties it |
| extra_text | STRING | Typed text wins over the dropdown. (tag:1.2) weights work. | |
| extra_append | BOOLEAN | false | append: add to the incoming value; replace: overwrite it |
| charopt | KISEKAE_CHAR | Character from the previous node; empty starts a new one |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| char | KISEKAE_CHAR | โ |