CyclicCharacterAndBackgroundPrompt
Your prompts on a loop — stop hand-editing every Wan segment
- merged_prompt
If you're chaining "infinite" Wan 2.1 VACE segments, the actual bottleneck isn't the GPU. It's you, remembering to change the prompt between runs so segment five isn't a clone of segment three. This node is that problem, automated: it cycles through lists of character, background, and extra prompts, and hands you one merged prompt per queue run. It's from heheok's small comfyui_wan2.1_vace_infinite_helpers pack, which exists to make long-form VACE generation less manual - you'd use it when you've got a script of variations you want to walk through without touching the graph every time.
How it works
Three multiline text inputs, each holding a JSON array of strings: character_prompts, background_prompts, and additional_prompts. On every execution the node reads an index file (cyclic_prompt_indices.json, written into your ComfyUI root folder), pulls one prompt from each list, and merges them into the output merged_prompt in the shape "{character}. In the background: {background}." with the additional string appended after it. Then it saves the incremented indices back to the state file.
The lists cycle independently. Give it 2 characters and 1 background and the background just repeats while the characters alternate - which is exactly what you want: same location, different subject, one after another. The trigger INT input is a dummy, there to force re-evaluation, and IS_CHANGED always returns True so the node fires on every queue run instead of getting cached away.
The two traps that will bite you
The shipped defaults aren't valid JSON. Open the node and the character field literally contains "A knight", "A samurai", "A wizard"] - note the missing opening bracket. If you hit Queue with the defaults untouched, json.loads throws "Invalid JSON input" and the run dies before the sampler ever sees it. Add the [, or better, paste your own properly-formed array in. Every list must be a JSON array of strings, brackets included.
The state file outlives your run. The node's position in your prompt list lives on disk, not in the workflow. Get it stuck mid-cycle and your next "random" prompt is actually whatever index the file says. To restart the loop, delete cyclic_prompt_indices.json from the ComfyUI root folder, or edit it to {"char_idx": 0, "bg_idx": 0, "add_idx": 0}. That file is also the reason a shared workflow behaves differently on your machine than on the author's.
One more quirk while you're in there: the merged string appends the additional list with no separator logic, so if your extras don't start with a space or period, you'll get phrases welded together. Keep the extras short and let them carry their own punctuation.
Install
Same as the rest of the pack. In ComfyUI Manager, search for comfyui_wan2.1_vace_infinite_helpers, or clone it:
cd path/to/ComfyUI/custom_nodes
git clone https://github.com/heheok/comfyui_wan2.1_vace_infinite_helpers
Then restart ComfyUI. The pack has no requirements.txt - it's stdlib plus torch, so there's nothing extra to pip install. Note the README suggests cloning into a folder named custom_scripts; Manager will use the repo name, and both work.
My take
Honest assessment: for a long automated run, this saves real fiddling, and it plays nicely with the pack's loop - each cycle advances the story. But if you're generating three clips, a prompt you change yourself is less machinery than a state file you'll forget about. The cycle is strict and sequential, not random; if you want actual variety across lists, keep each list longer than you think you need. And remember the first-segment rule that applies to the whole pack: disable the previous-video group for your very first generation, or there's nothing to loop off.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| character_prompts | STRING | "A knight", "A samurai", "A wizard"] | — |
| background_prompts | STRING | "in a forest", "on a mountain", "in a dungeon"] | — |
| additional_prompts | STRING | "cinematic lighting", "highly detailed", "photorealistic"] | — |
| trigger | INT | 0 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| merged_prompt | STRING | — |