Loop Step
The two-line node your for loop is secretly made of
- next_index
- continue
What it is
Loop Step takes a counter and a target and answers two questions: what's the next number, and are we done yet? Two integers in, next_index and continue out. That's it - and that's the point of it, because those two answers are the entire decision logic of any counted loop.
If you've used the For Loop Start / For Loop End pair from this same pack, you've already been running this node: For Loop End inserts a hidden Loop Step every round, with the step pinned to 1, to decide whether to expand another pass. Loop Step is that same node, exposed, so you can wire it by hand.
Which is the reason to reach for it: it's how you stride. A for loop in this pack counts in units of one. Want to walk a 512-frame batch in chunks of 64, sample every fourth frame, or step a denoise/strength schedule by 0.1-equivalent integer ticks? You build the loop out of While Loop Start / While Loop End and put Loop Step between them with step set to whatever you like.
How it works
The math is almost aggressively simple, and worth stating exactly because the boundary matters:
next_index = index + step
continue = next_index < total
Strictly less than. So with index=0, total=8, step=1: next is 1, 1 < 8 is True, keep going. The loop bodies see indexes 0 through 7 - eight passes - and on the pass where index=7 you get next 8, 8 < 8 is False, and the loop stops. Off-by-one complaints about loop nodes are almost always this line being read as <=.
Inputs and outputs
- index (INT, required) - the current counter. In a loop, you take this from the carried value that your While Loop Start hands out (the pack's convention is value slot 0 for the counter) rather than typing it.
- total (INT, required) - the target. A socket, so it can come from a primitive, a math node, or anything that produces an integer.
- step (INT, optional, default 1, min 1) - how far to jump. Minimum of 1, so no countdown loops and no negative strides; this counts up or not at all.
- next_index (INT out) → feed back into the loop's carried counter slot (i.e. into While Loop End's
initial_value0) so the next round starts from the new number. - continue (BOOLEAN out) → wire to While Loop End's
condition. When it goes False, the loop closes and the End's values are your results.
That pairing - next_index back into the state, continue into the End's condition - is the whole idiom. In a 5-iteration while loop with step=2 and total=10, your body sees 0, 2, 4, 6, 8 and stops.
Install
ComfyUI Manager, search ComfyUI-Practical-Tools, or:
cd ComfyUI/custom_nodes
git clone https://github.com/wenchengxiang/ComfyUI-Practical-Tools
Restart ComfyUI. Pure Python, no dependencies, no models - it registers under Practical-Tools/Logic along with the rest of this pack's loop family. The pack's requirements.txt pulls onnxruntime, nvidia-vfx and openai for entirely unrelated nodes; if those fail on your machine you get a [WCX Nodes Error] console line and everything else, including this one, loads fine.
Gotchas
It swallows bad input instead of complaining. The function wraps its arithmetic in a try/except (TypeError, ValueError) and returns (index, False) if the numbers don't make sense - which means a float sneaking in through a wire, or a string from some node that "returns numbers", doesn't raise an error. It silently ends your loop, and you get one iteration and a mystery. If a while loop stops after a single pass, check what's feeding total.
continue False is not an error state. A loop that ends after zero or one pass is usually just total being smaller than you think, or a step that overshoots immediately. index=0, step=64, total=32 is a one-pass loop.
Loop Step is a decision, not a mutation. It doesn't store anything. The counter only advances because you wired next_index back into the loop's carried value, and the loop only continues because you wired continue into While Loop End's condition. Miss either wire and you get a loop that never ends or a loop that never starts - both of which look like a frozen queue and neither of which errors out.
Counters are integers. Steps of 1, 2, 64 are fine; there's no 0.5, so a "ramp the denoise from 0.2 to 0.8" scheme has to be integers plus a conversion node downstream, not a fractional stride.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| index | INT | — | |
| total | INT | — | |
| stepopt | INT | 11–100000 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| next_index | INT | — |
| continue | BOOLEAN | — |