π Moon Anima Regional Patcher
The patcher that keeps your lynx on the left
- model
- mask_list
- positive_list
- negative_list
- patched_model
- POSITIVE
- NEGATIVE
Anima understands natural language better than any SDXL anime model, but it still has the same old failure: prompt two characters in one image and they'll start trading hair colors and jackets. Regional prompting fixes that by giving each half of the canvas its own prompt - and this node is the attention patch that makes it actually stick on Anima's architecture. The built-in regional conditioning that worked on SDXL doesn't port to a DiT, which is why the MoonNodes author rebuilt it, borrowing from Sen-sou's Comfyui-Anima-Regional-Conditioning (the README says so).
How it works
The mechanism is attention masking, from the MultiMaskCouple β ComfyCouple lineage. During sampling, the node wraps your Anima model and builds an attention bias each step: image tokens inside region A are blocked from attending to region B's prompt tokens, and vice versa. You're not editing the image or the latents - you're telling the attention heads which text they're allowed to listen to, spatially.
The sliders are where the craft lives, and the tooltips walk you through them:
cross_mask_strength(default 1.0) - isolation between distinct regions. At 1.0 the block is hard; drop it and regions get soft cross-influence, which fixes the "stuck-together collage" look when you've over-isolated.self_mask_strength(default 0.0) - spatial self-attention isolation. Crank this up when region boundaries leak despite cross-masking, but know the trade: regions become unaware of each other, so composition and shared lighting suffer. Start at 0 and only raise it when you must.base_strength(default 0.8) - how much the global base prompt (index 0) still affects each region. Higher blends shared style and lighting in; lower isolates each zone to its own prompt.start_percent/end_percent- the sampling window where regional masking is active. This is the parameter the community keeps coming back to: holding hard masks through the whole run is what produces visible seams. Let masking end around 0.6β0.8 so composition locks in early and the base conditioning blends the finish.base_ratio(default 0.0) - blend in a straight, unpartitioned generation. The tooltip is honest: values above 0 run the model twice per step. Anima is already slow, so treat this as a last resort.
Wiring it up
Feed it model (your Anima checkpoint), a mask_list (from Moon Mask Maker or Moon Mask Maker GUI), and a positive_list where index 0 is the base/global prompt and indexes 1..N match regions 0..N-1 - in practice that means the positive output of a Moon Indexed Encoder, which splits a BREAK-separated prompt box for you. negative_list is your usual negative, applied globally. Out the other side you get patched_model (into your KSampler) plus pass-through POSITIVE and NEGATIVE conditioning.
The pack's own Anima workflow uses base_strength 0.4, cross_mask_strength 1.0, self_mask_strength 0.2, base_ratio 0.1 at 22 steps with er_sde and the beta scheduler - a sane starting point rather than the defaults.
Install and gotchas
cd ComfyUI/custom_nodes
git clone https://github.com/m0rtus59/ComfyUI-MoonNodes.git
cd ComfyUI-MoonNodes
pip install -r requirements.txt
Then restart ComfyUI - or just search "ComfyUI-MoonNodes" in ComfyUI Manager. One trap: requirements.txt only pins google-genai (for the pack's Gemini nodes), but the pack imports that module at load time, so skip the pip step and none of these nodes will appear.
Two more things that bite: the inputs are list-typed, so positive_list[0] must be a non-empty base prompt or you'll get a runtime error, and mismatched mask sizes get resized to the first mask's shape silently. The author notes the repo was built with AI assistance and welcomes PRs - it works, but don't expect a polished production pack.
When to use it
Two characters with distinct attributes that keep bleeding into each other is the exact case. If you want to type the prompts directly in the node instead of feeding pre-encoded conditioning, grab the Advanced version - same patch, plus built-in encoding and a "stop early and blend" scheduler.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | The Anima diffusion model to patch with regional conditioning. | |
| mask_list | MASK | List of spatial masks corresponding to regional prompt zones (Zone 0, Zone 1, ...). | |
| positive_list | CONDITIONING | List of positive conditionings: prompt 0 is base/global, prompts 1..N correspond to regions 0..N-1. | |
| negative_list | CONDITIONING | Negative conditioning applied across the generation. | |
| base_strength | FLOAT | 0.800β1 | How much the global base prompt affects regional zones. Higher values blend more shared style/lighting into regions; lower values isolate the regional prompt. |
| start_percent | FLOAT | 0.000β1 | Sampling percentage (0.0β1.0) when regional conditioning starts being applied. |
| end_percent | FLOAT | 1.000β1 | Sampling percentage (0.0β1.0) when regional conditioning stops being applied. |
| cross_mask_strength | FLOAT | 1.000β1 | Cross-attention isolation between distinct regions (Zone A vs Zone B). 1.0 blocks bleed-through; lower values allow soft cross-regional influence. |
| self_mask_strength | FLOAT | 0.000β1 | Spatial self-attention isolation between regions. 0.0 maintains global scene coherence (shared lighting, perspective); higher values isolate spatial patches. |
| base_ratio | FLOAT | 0.000β1 | Direct blend ratio with the un-partitioned base generation. 0.0 is pure regional output. Values > 0 blend in the global base image (runs the model twice per step). |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| patched_model | MODEL | β |
| POSITIVE | CONDITIONING | β |
| NEGATIVE | CONDITIONING | β |