Batch Prompt Schedule π π π
Schedule a different prompt for every frame of your animation
- clip
- POS
- NEG
If you've ever wanted an animation where the scene actually changes - the prompt morphs from "a cat in a kitchen" to "a cat in a spaceship" over thirty frames - this is the node people mean when they say "FizzNodes." Batch Prompt Schedule is the flagship of FizzleDorf's FizzNodes pack, and it's the reason most people install it. It's the ComfyUI-native answer to Deforum's prompt scheduling, which is no accident: the code is openly built on the Deforum extension for A1111, and the README credits them.
How it works
You give it a list of keyframes - frame numbers with a prompt at each one - and it produces one conditioning per frame, interpolating the prompt (and its weight) smoothly between keyframes. The keyframe text looks like this:
"0" :"a cat in a kitchen",
"30" :"a cat in a spaceship, neon lights",
"60" :"a robot cat, cyberpunk city",
Format matters: it's parsed as JSON-ish, so keep quotes on the frame numbers and commas between entries. Split positive and negative text inside a single prompt with --neg:
"30" :"a cat in a spaceship --neg blurry, bad anatomy",
You can even embed math in backticks, where t is the current frame, max_f the last frame, and pw_aβpw_d are the four optional float inputs you can wire in. So something like "30": "a cat at `t/2` years old" is legal. It's a small language, but it covers a lot.
Under the hood, Batch Prompt Schedule parses your keyframes, fills in pre_text / app_text around every prompt, splits positives from negatives, and interpolates a weight that shifts from the current keyframe's prompt to the next one's, frame by frame. On frames between keyframes it blends the two conditionings with weighted composable diffusion (the same addWeighted trick ComfyUI itself uses for conditioning averages), so the transition is a true prompt morph rather than a hard cut.
The inputs and outputs that matter
You'll actually set three things: text (your keyframe schedule), clip (the CLIP of your checkpoint), and max_frames (how long the animation is - this also sets the batch size). print_output is a debugging toggle that dumps each frame's evaluated prompt to your console. start_frame and end_frame look important but are genuinely print-only - they only affect that console output, not the batch. The pw_aβpw_d floats exist for backtick math.
The outputs are POS and NEG - both are a batch of max_frames conditionings. Wire them into a sampler alongside a latent batch of the same size (typically from AnimateDiff), and each frame gets its own prompt. The README's example uses a deterministic sampler (Euler) and runs the whole thing in about 4.7 GB of VRAM.
Install
Either way, the node lives in the "FizzNodes π π π " menu section:
cd ComfyUI/custom_nodes && git clone https://github.com/FizzleDorf/ComfyUI_FizzNodes.git
cd ComfyUI_FizzNodes && pip install -r requirements.txt
Or skip all that and install "FizzNodes" via ComfyUI Manager, then restart. Dependencies are just numpy, pandas, and numexpr - no model downloads, nothing heavy.
Where people get burned
The classic mistake is expecting a single value out of a batch node. Batch Prompt Schedule returns conditionings for all frames at once - it's designed to feed a sampler that consumes a full batch. If you're getting confused outputs or errors, check that your latent batch size matches max_frames. And if your text doesn't parse, the node will throw a "Key Frame string not correctly formatted" error - check your quotes and commas before suspecting the pack. If you need one prompt at the current frame only (driven by a frame counter), use the non-batch Prompt Schedule node in the same pack instead.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | "0" :"", "11" :"", "23" :"", "35" :"", "47" :"", "59" :"", "71" :"", "83" :"", "95" :"", "107" :"", "119" :"" | β |
| clip | CLIP | β | |
| max_frames | INT | 1201β999999 | β |
| print_output | BOOLEAN | false | β |
| pre_textopt | STRING | β | |
| app_textopt | STRING | β | |
| start_frameopt | INT | 00β9999 | β |
| end_frameopt | INT | 00β9999 | β |
| pw_aopt | FLOAT | 0.0-9999β9999 | β |
| pw_bopt | FLOAT | 0.0-9999β9999 | β |
| pw_copt | FLOAT | 0.0-9999β9999 | β |
| pw_dopt | FLOAT | 0.0-9999β9999 | β |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| POS | CONDITIONING | β |
| NEG | CONDITIONING | β |