LC Flux 3 Layout Prompt 🗺️
The table FLUX 3 wants, built from your boxes
- elements
- prompt
- info
Why you'd reach for it
FLUX 3 was trained with an element table stapled to its caption. Not a sentence about boxes - an actual JSON array of {id, bbox, desc} rows, in BFL's own format, where boxes are [y_min, x_min, y_max, x_max] on a 0–1000 grid. BFL ships that format in a system-prompt file, and if you've met Ideogram 4 tooling you've seen the idea before: the model doesn't want prose, it wants a schema, and the schema is where the layout lives.
You can assemble that schema by hand. Nobody enjoys it. LC Flux 3 Layout Prompt takes the elements array from LC Bounding Boxes - or from core's Create Bounding Boxes - and produces the finished prompt string: your caption, your <1>/<2> placeholders resolved to real box ids, then the table appended in the trained format. It also tells you which boxes you forgot to mention, which is the part that quietly ruins generations.
How it works
Two tables, one choice. When nothing changes position, you get the layout table - the rows describe a picture that doesn't exist yet, each with an id, a bbox and a description. When at least one box is a change, a move or a remove, you get the edit table instead: {id, from, src_bbox, tgt_bbox, desc}, where from names the reference image the object came from. That's the difference between "draw this" and "take the thing from here and put it there."
Placeholders are the trick worth learning. Write <1> and <2> in the prompt box and they're replaced with box 1's and box 2's real ids, in order - so your prompt stays readable while the model sees <earring_1>. If you prefer, write the id yourself. Every box should be named once; the info output lists the ones you missed so you can go back and add them.
Text boxes get special treatment: a box typed as text has its literal words appended to the description in quotes, which is how you get signage, labels and shirt slogans to come out spelled the way you meant.
The last bit is the closing clause. For edits, keep_rest appends BFL's own sentence - everything else stays identical to the source - unless your prompt already contains something that says the same thing, in which case it stays out of the way. Skipping it is the fastest way to get a model that helpfully redraws the entire background.
The inputs that matter
- prompt - the caption for a new picture, or the instruction for an edit. Multiline, with
<1>/<2>placeholders. - elements - the array from a box node. Contains no boxes? The prompt passes straight through unchanged, so this node is safe to leave wired in while you iterate.
- table -
auto,layout (new picture)oredit (from a reference).autopicks edit whenever a box changes, moves or removes something. Force it when the box kinds are lying to you. - keep_rest (optional, default on) - the closing "everything else stays identical" clause for edits.
What comes out
prompt, a plain STRING that goes into a CLIP Text Encode like any other prompt - the table is appended as text, so nothing special is needed downstream. info is a short human-readable status: which table was used, how many boxes, and which ids don't appear in your prompt. Wire it to a Show Text or an LC Note, or just ignore it until something comes out wrong.
One warning that's easy to get burned by: this is a positive-prompt builder. Table text in a negative encoder is not going to do what you want. Keep prompt on the positive branch only.
Install
ComfyUI Manager → search ComfyUI LC123 Nodes, or:
cd ComfyUI/custom_nodes
git clone https://github.com/lonecatone23/ComfyUI_LC123_nodes
No dependencies - the pack ships no requirements.txt, no install script, no model downloads. Restart, confirm the [LC123] + lines in the console, Ctrl+F5 if you updated an existing install. FLUX 3 weights and the text encoder are separate; this node only writes the prompt.
Common issues
The model ignores half your objects. Run the info output and read it. A box you never named in the prompt is a box the model has no instruction for, and the table row alone is weaker signal than you'd hope.
An edit redraws everything. Check two things: keep_rest is on, and your prompt doesn't already claim everything changes. Also confirm table resolved to edit - if every box is new, auto will happily produce a layout table for an edit.
Ids don't match what you expected. Placeholders map by position, not by name: <2> is the second box in the array, whatever it's called. Reorder boxes and your prompt points somewhere else.
Empty table in the output. No elements means no table, and no table means your prompt back verbatim. Not a bug, but it looks like one if you've connected the wrong socket.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| prompt | STRING | The caption (new picture) or instruction (edit). Write <1>, <2> for box 1, box 2, or the box ids themselves (<earring_1>). Every box should be named once. | |
| elements | ARRAY | The boxes from LC Bounding Boxes (or Create Bounding Boxes). | |
| table | COMBO | auto | auto: the edit table when a box changes, moves or removes something, otherwise the layout table. |
| keep_restopt | BOOLEAN | true | Edits: end with BFL's closing clause that everything else stays identical. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| prompt | STRING | — |
| info | STRING | — |