π Moon Regional Patcher
The node that makes separate prompts actually stay in their lanes
- model
- clip
- mask_list
- positive_list
- negative_list
- MODEL
- POSITIVE
- NEGATIVE
This is the flagship of the MoonNodes pack, the "central hub" the README keeps pointing back to. Regional prompting splits the canvas so each area follows its own prompt - the left character keeps her red hair, the right one keeps his blue - and MoonRegionalSampler is the node that actually makes the split stick. It takes your model, your masks, and your per-area conditioning lists, and returns a patched model plus ready-to-use positive and negative conditioning that go straight into a plain KSampler.
Everything else in the pack's regional half exists to feed this node. That's the architecture to keep in mind.
How it works
Two things happen inside. First, it assembles the conditioning: the block at index 0 of each list is the base prompt, and each region's conditioning is masked by its corresponding mask via ConditioningSetMask, then combined into one final positive and negative. The mode selector changes how region prompts relate to the base:
- Merge (default) - region conditionings are blended in by their masks, attention-style. Cleaner conceptually; this is what you usually want.
- Concat - each region prompt is physically appended to the base prompt's tokens before masking. Richer context per region, heavier on the text encoder.
Second, and more interesting, it patches the model's attention using the pack's attention-coupling core (a descendant of MultiMaskCouple, which itself descends from ComfyCouple). The patch makes each masked area attend to its own prompt instead of the whole canvas. That's the part that stops attribute bleeding that plain masked conditioning alone doesn't fully fix.
Then there's head_start_percent (0β1, default 0). This is the knob for the classic regional-prompting failure mode: hard masks held through the entire generation produce that collaged look with visible seams and regions that ignore each other. Setting head_start_percent isolates self-attention for the first X% of steps - keeping regions separate while the layout forms - then releases them to blend for the rest. The known-good playbook is to start at a small value like 0.1β0.2 and only raise it when attributes are bleeding.
The ports
model,clip- from your checkpoint loader.mask_list(MASK) - the list from Moon Mask Maker / GUI.positive_list,negative_list(CONDITIONING) - lists from Moon Indexed Encoder (or one CLIP encode for the base and per-region encodes you index yourself).mode- Merge or Concat.head_start_percent- the seam/bleed control.
Outputs: MODEL (the attention-patched model), POSITIVE, NEGATIVE - wire all three into a normal KSampler and continue like you never did anything unusual.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/m0rtus59/ComfyUI-MoonNodes.git
cd ComfyUI-MoonNodes && pip install -r requirements.txt
Restart. Works with whatever SDXL-style checkpoint you already load - no downloads.
Honest caveats
Keep every list in the same order: masks, positive regions, negative regions all indexed together, with the base prompt always at 0. The packed workflow uses CLIPSetLastLayer before this node for better results - worth copying. And a real limitation: the attention patch targets the classic UNet layout, so this node is not for Anima's DiT architecture - the pack ships separate MoonAnimaRegionalPatcher nodes for that. If regional prompting is new to you, expect to fiddle with head_start_percent; the technique is genuinely fiddly, and any guide that promises zero tuning is lying.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | β | |
| clip | CLIP | β | |
| mask_list | MASK | β | |
| positive_list | CONDITIONING | β | |
| negative_list | CONDITIONING | β | |
| mode | COMBO | Merge | 2 options: Merge, Concat |
| head_start_percent | FLOAT | 0.000β1 | β |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| MODEL | MODEL | β |
| POSITIVE | CONDITIONING | β |
| NEGATIVE | CONDITIONING | β |