Prompt Schedule NodeFlow π π π
Build your prompt schedule one node at a time instead of writing JSON
- INT
- STRING
FizzNodes' schedule format is just text, but it's specific text - "frame" : "prompt", pairs with exact quotes, and one stray comma kills the parse. Prompt Schedule NodeFlow exists so you never have to write that by hand. It's a builder node: each one takes a single prompt and how long it should last, appends it to the growing schedule string, and hands you the result. Chain a few together and you've assembled a whole keyframe schedule visually, without ever touching raw JSON.
It's the "write half" of the pack's NodeFlow pair. The strings it produces are meant to flow forward into Prompt Schedule NodeFlow End, which does the actual encoding.
How it works
Think of it as accumulating a JSON string one segment at a time, with a running total of frames. text is the prompt for this segment, num_frames extends the running total, and the node stamps the keyframe at the new total. A concrete chain shows the pattern - and these are the actual numbers the node produces, not a simplification:
- NodeFlow A: text
"a cat sitting", num_frames30β writes"0": "a cat sitting", running total 30 - NodeFlow B: text
"a cat yawning", num_frames15β appends"45": "a cat yawning", running total 45 - NodeFlow C: text
"a cat sleeping", num_frames20β appends"65": "a cat sleeping", running total 65
The first node's prompt is always keyed at frame 0; every later keyframe lands at the cumulative total, and that final total is the length of your animation - exactly the max_frames the End node wants. Because the engine treats each keyframe pair as a crossfade, your prompts blend across those spans rather than snapping. Worth knowing up front: num_frames isn't literally "how many frames this prompt owns" - it's how much the running total grows, and the keyframe sits at the grown total.
Two outputs come out of every node: the INT output is the running total (the max so far), and the STRING output is the accumulated schedule text. The optional in_text takes the previous node's string; max_frames takes the previous node's running total. Wire those two connections, set your prompt and segment length, and chain on.
Why you'd bother
For a two-keyframe test, honestly, don't - just type the JSON into a Prompt Schedule node. But NodeFlow earns its keep once your animation has more than a few beats. Each segment stays a self-contained, reorderable node; you can bypass one without editing text; and the running total is computed for you, so you never do the "wait, what frame did that last keyframe end on?" arithmetic. It also plays nicely with workflows you share - a NodeFlow chain is a lot more legible to someone else than a wall of schedule text.
Install and gotchas
It's part of the FizzNodes pack: ComfyUI Manager β search FizzNodes β install β restart. Manual install is the standard clone:
cd ComfyUI/custom_nodes
git clone https://github.com/FizzleDorf/ComfyUI_FizzNodes
cd ComfyUI_FizzNodes && pip install -r requirements.txt
numpy, pandas, numexpr - that's all. Find it under FizzNodes π
π
π
β ScheduleNodes.
The one trap is forgetting the two-wire handoff: if you don't route the previous node's INT into the next node's max_frames, the running totals reset and your keyframes all collide at frame 0. The STRING/in_text pair is obvious; the integer handoff is the one people miss, and the symptom is a schedule that only ever shows the last segment. Also note this node doesn't take a clip - it has no idea about encoding. That's what the End node is for.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | β | |
| num_frames | INT | 240β9999 | β |
| in_textopt | STRING | β | |
| max_framesopt | INT | 00β999999 | β |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| INT | INT | β |
| STRING | STRING | β |