Prompt Random Choice
Randomize Background, Weather, and Time of Day Every Run
- selected_text
- selected_text_safe
You want 100 images from one workflow without touching the prompt between runs - same character, but the background, the weather, the time of day all change on their own. That's the job of Prompt Random Choice (class PromptRandomChoice): you give it a list of prompt fragments and it rolls one each execution, "prompt gacha" style, and hands you back a plain string you can slot into your positive prompt.
How it works
ComfyUI already ships {a|b|c} syntax that picks an alternative at CLIP Text Encode time - the "bracket trick" people use to batch prompt variety. This node is the same idea one stage earlier: it resolves the choice upstream in the graph, picks a single option, and outputs a normal STRING. Two consequences matter:
- Only the chosen text ever reaches the text encoder. That's the README's selling point for LoRA trigger words - if you're putting
trigger1|trigger2in here, the losers never flow downstream, so a LoRA's trigger never leaks into the prompt when it isn't wanted. (Note: this does not load or unload LoRAs; it only keeps stray strings out.) - The output is a regular string, so it can feed anywhere a string goes - a prompt, a filename, a string-join node. And because the choice is resolved in the graph, you can see it: after each run the node title updates to
Ch: lake, orCh: lake (2/3)when a choice is being held.
The mechanics: the node splits options_text on | or real newlines, trims surrounding spaces and trailing commas from each fragment, drops empties created by repeated delimiters, and treats () as an explicit empty option. The pick itself is done server-side with Python's secrets.choice(). The IS_CHANGED hook returns a fresh timestamp every call, so the node re-executes for every queued run - queue 100 and every one re-rolls.
The inputs and outputs that matter
Just two inputs, both worth understanding:
options_text(multiline string): your candidate list. Newlines or|both work as separators, so this parses fine:town| girl's room| park| lake| castle, fortress| forest| sea| coffee shop()is an explicit empty candidate -()|(full body:0.9)means "sometimes add nothing, sometimes add a framing tag." To bias the odds, repeat an option:day|day|day|sunset|nightgives you a bright scene most of the time with the occasional evening.change_every(int, default 1): how many consecutive runs hold the same choice. Set it to 3 and the same pick repeats three times before re-rolling - handy when you want a couple of images per setting to compare, and the title shows the progress (Ch: lake (2/3)).
Two outputs:
selected_text: the trimmed pick, ready to concatenate into a prompt.""if()won.selected_text_safe: a filename-safe version (spaces, commas, slashes,()and{}all scrubbed;emptywhen the pick was empty). Wire this one into an image-save filename and you'll actually be able to tell the results apart.
The setup the author recommends
Wire selected_text into a string-join node - the README suggests kjnodes' Join String Multi - and let that own the comma separators, then feed the result into your positive prompt. Drop several choice nodes in the graph, one each for background, weather, lighting, and composition. They're fully independent, so each one rolls separately; that's the whole "vary everything at once" pattern.
Installing it
Lightweight pack - no dependencies, no models, just a clone and a restart:
- ComfyUI Manager: search
ComfyUI-PromptRandomChoiceand install. - Manual:
cd ComfyUI/custom_nodes git clone https://github.com/ruminar/ComfyUI-PromptRandomChoice
GPL-3.0, like ComfyUI itself.
Common issues
- An option never shows up: check for doubled separators - a trailing
|followed by a newline, for example - because empty fragments get dropped rather than kept. Want an explicit "nothing" slot? Write(). - Weights feel wrong: remember repeats count.
day|day|day|sunset|nightreally is 3:1:1, and a stray empty line silently skews it. - You pasted
{day|night}and it's showing up literally: this node doesn't parse the text-encoder's{}syntax (that's the Ex variant's job, and even it treats braces as expansion markers, not literals). Drop the braces here. - Title not updating: the
Ch: …display runs in the bundled browser extension, so restart ComfyUI and hard-refresh if it lags.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| options_text | STRING | town, girl's room, park, lake, flower garden, castle, fortress, forest, grasslands, sea, snowy landscape, mountain, flower field, starry sky, coffee shop, | — |
| change_every | INT | 11–999999 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| selected_text | STRING | — |
| selected_text_safe | STRING | — |