Nodes/ComfyUI_LC123_nodes/LC MOSS Layout Prompt 🗺️
ComfyUI Node

LC MOSS Layout Prompt 🗺️

Turn your drawn boxes into the JSON MOSS Image actually reads

By lonecatone23·Created 3 months ago·Updated a day ago· 46
LC MOSS Layout Prompt 🗺️
  • elements
  • prompt
  • width
  • height
  • info
◄prompt►
◄canvassingle►
◄meta►
◄palette►
◄width0►
◄height0►
◄character_boxes►

You've drawn the boxes - hat here, character there, "OPEN" in the corner. That's the hard part over with, and it's still useless: MOSS Image doesn't take boxes as an image or a list of pixel rectangles. It takes a layout prompt: one structured block where each box is an object, a character or a block of text with its own caption, its own palette, and a position measured in pixels from the centre of the canvas.

LCMOSSLayoutPrompt writes that block for you - pure string building, no model, no VRAM - and that's the difference between hoping the model puts the hat on the head and telling it to.

Why layout in the caption at all

Prompt adherence is global: ask for two people and their hair colours bleed. That's why regional prompting keeps getting rebuilt for every new architecture. What changed in 2026 is that some models stopped bolting layout on afterwards and put it in the caption schema itself: Ideogram 4 was trained to accept bounding boxes, so it handles overlap and nesting that masked conditioning handles badly. MOSS Image pushes the same idea further - not just where things are, but a per-item caption and a per-item palette, plus a top-level statement of what kind of page you're making.

Your prompt stops being prose and becomes a small scene graph. Great for control, less great if you'd rather not hand-write JSON.

How it builds the prompt

The node takes the elements array straight off a box editor - LC Bounding Boxes in this same pack, or ComfyUI's own Create Bounding Boxes - and keeps entries that carry a bbox. It takes the canvas size from the elements (LC Bounding Boxes stamps its own on each one), snaps width and height down to a multiple of 16, and converts every box from the editor's 0–1000 grid into pixel edges measured from the canvas centre, top/left floored, bottom/right ceiled. That's OpenMOSS's own convention, and the output declares it: bbox_coord_space: abs_centralized, bbox_format: yxyx.

Each element becomes one item. Text boxes get label: "text" and carry their exact wording; boxes marked as characters (or listed by number in character_boxes) get label: "character"; the rest are object. Per-box palettes ride along. Above them sits a summary block with your whole-picture caption, the medium tags, the canvas type and the overall palette.

The fields you set, and the four outputs

  • prompt - the whole picture: scene, style, light, mood. Each box only describes its own part. Left empty, the node joins your box descriptions into a caption - a fallback, but the weaker option.
  • elements - the boxes. Draw the background first, the foreground last, because that order becomes layering. No boxes in, no layout out.
  • canvas - single, multi_panel (comic panels, split screen) or collage (moodboard, sticker sheet). One word, and it changes what the model thinks the page is, so don't leave it on single for a sticker sheet.
  • meta - comma-separated medium tags (photo, movie poster). palette - colours for the whole picture (#1a1a1a, warm beige). Both optional, both free wins. width/height - optional; 0 inherits the canvas the boxes were drawn on.
  • character_boxes - "1, 3" marks extra boxes as characters by position.

Out come prompt (the layout JSON - wire it into your positive prompt's text input), width and height (INTS - feed them to the empty latent so the boxes can't drift) and info (a plain-language report).

Install

Manager: search ComfyUI_LC123_nodes. Manually:

cd ComfyUI/custom_nodes
git clone https://github.com/lonecatone23/ComfyUI_LC123_nodes.git

Restart. No requirements.txt, no pip step. Check the console for [LC123] + lines and make sure __init__.py sits directly in ComfyUI/custom_nodes/ComfyUI_LC123_nodes/. MOSS Image itself is separate - the pack's Model Optimizer lists MOSS Image (SFT and Base), but it needs a ComfyUI build with native MOSS-Image support.

Where people get burned

Read the info output - that's what it's for. Park it in a Show Text node while you set up. It reports how many objects, characters and text items went in, and warns about the real problems: a box with no description, a text box with no text to write.

Width and height must equal the latent, and they snap. Type 1000 and you get 992, because it rounds down to a multiple of 16 - sample a 1024 latent against that and your boxes are stretched. Unsure? Leave both at 0 and drive the latent from the node's own width/height outputs.

Core Create Bounding Boxes doesn't carry a canvas size. Use it and the node falls back to 1024×1024 - set width/height yourself, or use LC Bounding Boxes, which stamps the real size and warns when the two disagree.

CategoryLC123/MOSS Image

Inputs (8)

NameTypeDefaultDescription
promptSTRINGThe whole picture: scene, style, light, mood. Each box describes only its own part.
elementsARRAYThe boxes from LC Bounding Boxes (or Create Bounding Boxes). Draw the background first, the foreground last.
canvasCOMBOsinglesingle = one picture. multi_panel = comic panels or a split screen. collage = a moodboard or sticker sheet.
metaSTRINGMedium / genre tags, comma separated: photo, portrait, movie poster, etc. Empty = none.
paletteSTRINGColours for the whole picture, comma separated (#1a1a1a, warm beige). Empty = none.
widthoptINT00–16384Size of the picture you render. 0 = the boxes' canvas (LC Bounding Boxes). Must match the latent or the boxes land in the wrong place.
heightoptINT00–163840 = the boxes' canvas.
character_boxesoptSTRINGExtra boxes to mark as characters by number ("1, 3"). Boxes set to character in LC Bounding Boxes already are.

Outputs (4)

NameTypeDescription
promptSTRINGThe layout prompt: wire it into the positive prompt's text.
widthINTThe width the boxes were placed in: use it for the latent.
heightINTThe height the boxes were placed in.
infoSTRINGWhat went in, and anything to fix.