Nodes/Nodes for use with real-time applications of ComfyUI/String Control πŸ•’πŸ…‘πŸ…£πŸ…
ComfyUI Node

String Control πŸ•’πŸ…‘πŸ…£πŸ…

Animate your text in a real-time ComfyUI graph

By ryanontheinsideΒ·Created 2 years agoΒ·Updated about a year agoΒ· 82
String Control πŸ•’πŸ…‘πŸ…£πŸ…
    • STRING
    β—„always_executetrueβ–Ί
    β—„stringsfirst string second string third stringβ–Ί
    β—„steps_per_cycle30β–Ί
    β—„movement_typesineβ–Ί

    You've got a live ComfyUI workflow running once per frame - think ComfyStream or a StreamDiffusion-style pipeline - and you want the prompt to drift while it runs, not just the seed. That's the entire job of String Control πŸ•’πŸ…‘πŸ…£πŸ…. It's a stateful node that outputs a string, and every time the graph executes it quietly advances an internal clock and hands you a different line from the list you gave it. Wire the output into a CLIP Text Encode and your positive prompt starts to cycle on its own. No API, no key, no Python. Just text that changes over time.

    It's one node in ryanontheinside's real-time pack - the same author behind the ComfyStream-adjacent "everything reactivity" suite - and it exists because in real-time land, nobody is clicking "Queue Prompt" a hundred times a minute. The graph itself is the clock.

    How it works

    Under the hood it's a phase accumulator. Each execution bumps an internal phase by 1 / steps_per_cycle, then runs your chosen movement pattern over that phase and uses the result to pick an index into your list of strings. So your list is a track and the pattern is how it's traversed:

    • sine (the default) sweeps up through your strings, then back down. Smooth, looping, easy on the eyes.
    • sawtooth sweeps forward and hard-resets to the start.
    • square snaps between the first and last line - good for a coarse two-state toggle.
    • bounce, exponential, random_walk, smooth_noise and friends are the same idea with different temperaments.

    static pins the first line, which sounds useless until you realize it's a handy way to temporarily freeze a node mid-tweak. One important thing: the output is always a whole string. Sine doesn't interpolate characters, it just decides which entry in your list you're currently closest to. If you want smooth blending, put your interpolation downstream.

    The inputs that matter

    • strings - one string per line. This is your content. The default is first string / second string / third string, so don't be confused when it starts cycling gibberish; replace it with real prompts.
    • steps_per_cycle (default 30) - how many executions one full cycle takes. On a 30 fps runner, 30 is about a second per cycle. This is your speed knob.
    • movement_type - the pattern above.
    • always_execute (default on) - leave it on. When it's on the node re-evaluates every execution; that's what makes the clock tick. If you turn it off, the output freezes the moment nothing upstream changes, and it's very easy to mistake that for a broken workflow.

    Output: a single STRING. That's it. Into CLIP Text Encode positive, or negative if you want the anti-prompt to change too.

    Installing it

    Same as any node in this pack. Easiest via ComfyUI Manager - search "Control Nodes" or just "Realtime" and install. Manual route:

    cd ComfyUI/custom_nodes
    git clone https://github.com/ryanontheinside/ComfyUI_RealtimeNodes
    cd ComfyUI_RealtimeNodes
    pip install -r requirements.txt
    

    Then restart ComfyUI. Watch the casing - the repo is RealtimeNodes, and the README's own clone command typo's it to RealTimeNodes. GitHub is case-sensitive, so a copy-paste from the wrong source fails silently-ish with a 404. Note the requirements include mediapipe, which this particular node never touches - it's for the pack's vision half. You can ignore it; the whole pack installs together.

    Where people get burned

    The classic one is expecting String Control to animate inside a normal ComfyUI session. It won't. A regular single-run graph executes once and the node's clock never moves until you queue another run. It's built for once-per-frame runners, not for batch mode - that's the "real-time" in the pack's name. Also, if your list has one line, all patterns output that one line forever; the node won't complain. For live performance where you want prompts swapping on a beat, this is the one you'll reach for before you graduate to audio-reactive stuff.

    The πŸ•’πŸ…‘πŸ…£πŸ… suffix on every node is the pack's brand - Ryan's real-time series. You'll see it in every menu in this pack, and it's how you tell the RealtimeNodes family from lookalikes at a glance.

    Categoryreal-time/control/value

    Inputs (4)

    NameTypeDefaultDescription
    always_executeBOOLEANtrueWhen enabled, the node updates every execution
    stringsSTRINGfirst string second string third stringList of strings to cycle through (one per line)
    steps_per_cycleINT301–1000Number of steps to complete one full cycle
    movement_typeCOMBOsinePattern of value changes over time

    Outputs (1)

    NameTypeDescription
    STRINGSTRINGβ€”