RS Character Position
What the X/Y actually controls (it isn't where the body goes)
- building_pipe
- building_pipe
The most expensive misunderstanding in regional prompting: you move a character's centre, run it, and the person doesn't budge. You conclude the node is broken. It isn't. Coordinates here pick which prompt owns which patch of canvas - they're an attention partition, not a placement control. Get that straight and the rest of this node becomes obvious.
The mechanism, in one paragraph
Each character gets a normalised centre, and the sampler builds a nearest-centre partition of the whole image: every token belongs to exactly one character. Positive cross-attention then lets a token read the common scene prompt plus its own character's text, and nothing from the others. Boxes work the same way but claim a rectangle instead of a slice. So X/Y decides which words apply to which pixels - and because it's the model that decides what a person's body does inside that region, small coordinate nudges change surprisingly little on a single-character image, where one character owns the entire canvas anyway.
Doing it with the box or without
RS Character Position is the position role in the modular pipe: rows 1–10, each with geometry (point or box), x, y, width, height, all 0–1. character_count controls how many rows show, and the tooltip is precise about what it means - the prompt node's count determines the active regions, this node's count determines which slots get positions. Unlisted rows default to centre.
Points are quick and they behave well for the classic case: two people, one at 0.3 and one at 0.7, both at y 0.5, wide canvas, done. Coincident points spread left to right in slot order, and the sampler records original and effective coordinates separately, so two characters both sitting at 0.5 still come out side by side rather than stacked on each other.
Boxes are width and height around the centre, and they buy you two things. Overlap control - boxes take priority over point regions in mixed layouts, and overlapping boxes share their captions. And text regions, which can only exist in a box, since you can't write into a point.
The shipped counter-example is worth copying: two people plus the word HELLO is character_count = 3, slot 3 set to kind = text, geometry box, with the word in its string and a box placed where you want the lettering. Width 0.25 and height 0.15 are a sane starting rectangle for a word.
The layout guide
The node draws a guide of the current layout into its UI, and Finalize shows the complete line so you can see the whole arrangement in one place before sampling. Use it as a sanity check, not a preview. The author's own wording is that layout is "a guide, not a composition guarantee", and the validation notes back that up: requesting four people in a 2×2 grid produced twelve in one run and ten in another. Horizontal arrangements are the strongest tested case for a reason - a wide canvas with two characters maps cleanly onto two prompt regions, whereas rows and grids invite duplication.
Wiring
Output is building_pipe, same as the other role nodes. Connect Position, Prompt and LoRA in any order, finish with RS Finalize Character Pipe, then feed the sampler.
cd ComfyUI/custom_nodes
git clone https://github.com/raspie10032/ComfyUI_RS_MultiCharacter_Sampler.git
# restart ComfyUI
That's the whole install - the core pack has no root requirements file and leans on ComfyUI's own torch/NumPy/Pillow. Or install RS MultiCharacter Sampler from ComfyUI Manager; just don't do both, since a Manager copy alongside a Git checkout is the usual cause of a duplicated or half-loaded node list.
Failure modes I'd actually expect
Box geometry that runs off the canvas gets an explicit error with the fix in the message: move the centre inward or shrink the box. Handle it by keeping x ± width/2 and y ± height/2 inside 0–1.
Text rows without box geometry fail at Finalize. So do text rows carrying a LoRA - spelling has no character design attached.
And the classic: two characters with the same centre and the same prompt-ish text will blend into one extremely well-dressed person. Push the centres apart before you start fiddling with weights.
Finally, when one character occupies 80% of the frame and the other is squeezed into a corner, the composition is telling you the region sizes are the problem. Widen the canvas to 1536×768 rather than fighting the partition - that's the shape this pack was validated on.
Inputs (52)
| Name | Type | Default | Description |
|---|---|---|---|
| character_count | INT | 21–10 | Show all slots 1–N together. Prompt count determines the active regions; LoRA/Position counts determine which settings they supply. / 1~N번 설정을 함께 표시합니다. 최종 인원수는 프롬프트 노드 기준입니다. |
| character1_geometry | COMBO | point | 2 options: point, box |
| character1_x | FLOAT | 0.500–1 | — |
| character1_y | FLOAT | 0.500–1 | — |
| character1_width | FLOAT | 0.400.01–1 | — |
| character1_height | FLOAT | 0.800.01–1 | — |
| character2_geometry | COMBO | point | 2 options: point, box |
| character2_x | FLOAT | 0.500–1 | — |
| character2_y | FLOAT | 0.500–1 | — |
| character2_width | FLOAT | 0.400.01–1 | — |
| character2_height | FLOAT | 0.800.01–1 | — |
| character3_geometry | COMBO | point | 2 options: point, box |
| character3_x | FLOAT | 0.500–1 | — |
| character3_y | FLOAT | 0.500–1 | — |
| character3_width | FLOAT | 0.400.01–1 | — |
| character3_height | FLOAT | 0.800.01–1 | — |
| character4_geometry | COMBO | point | 2 options: point, box |
| character4_x | FLOAT | 0.500–1 | — |
| character4_y | FLOAT | 0.500–1 | — |
| character4_width | FLOAT | 0.400.01–1 | — |
| character4_height | FLOAT | 0.800.01–1 | — |
| character5_geometry | COMBO | point | 2 options: point, box |
| character5_x | FLOAT | 0.500–1 | — |
| character5_y | FLOAT | 0.500–1 | — |
| character5_width | FLOAT | 0.400.01–1 | — |
| character5_height | FLOAT | 0.800.01–1 | — |
| character6_geometry | COMBO | point | 2 options: point, box |
| character6_x | FLOAT | 0.500–1 | — |
| character6_y | FLOAT | 0.500–1 | — |
| character6_width | FLOAT | 0.400.01–1 | — |
| character6_height | FLOAT | 0.800.01–1 | — |
| character7_geometry | COMBO | point | 2 options: point, box |
| character7_x | FLOAT | 0.500–1 | — |
| character7_y | FLOAT | 0.500–1 | — |
| character7_width | FLOAT | 0.400.01–1 | — |
| character7_height | FLOAT | 0.800.01–1 | — |
| character8_geometry | COMBO | point | 2 options: point, box |
| character8_x | FLOAT | 0.500–1 | — |
| character8_y | FLOAT | 0.500–1 | — |
| character8_width | FLOAT | 0.400.01–1 | — |
| character8_height | FLOAT | 0.800.01–1 | — |
| character9_geometry | COMBO | point | 2 options: point, box |
| character9_x | FLOAT | 0.500–1 | — |
| character9_y | FLOAT | 0.500–1 | — |
| character9_width | FLOAT | 0.400.01–1 | — |
| character9_height | FLOAT | 0.800.01–1 | — |
| character10_geometry | COMBO | point | 2 options: point, box |
| character10_x | FLOAT | 0.500–1 | — |
| character10_y | FLOAT | 0.500–1 | — |
| character10_width | FLOAT | 0.400.01–1 | — |
| character10_height | FLOAT | 0.800.01–1 | — |
| building_pipeopt | RS_MC_BUILD_PIPE | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| building_pipe | RS_MC_BUILD_PIPE | — |