π Z2J Subject Action
Verbs, manufactured on demand β Z2J Subject Action does the legwork of dynamic prompts
- text
Description tells the model what the subject is; action tells it what's happening, and that's where a still image earns its sense of life. Z2J Subject Action generates that motion half of the sentence for you - deterministic, reproducible, and unbothered by writer's block. It's the sibling of Z2J Subject Pose in the ComfyUI-Zero2JSON pack: pose gives you the static body configuration, action gives you the movement and energy.
In the FLUX2-JSON workflow it's meant to feed the action field of a FLUX2_SubjectCreator, so the structured prompt ends up with a clean "subject does X" component instead of a run-on. If you're doing character studies or batch exploration, this is the node that keeps the "doing" part fresh across a run.
How it works
Standard position-as-seed machinery: the node hashes (seed, prompt_index, slot) with xxhash32 and picks a template plus one word per pool. The subject_action_default.json profile has 4 templates over four pools - verb (24 options), direction (11), modifier (12), quality (9) - for about 114,000 combinations. That's a genuinely big action vocabulary: verbs like reaching, lunging, or drifting combine with directional phrases and a quality word, so you get "reaching forward, deliberately, with elegant form" rather than the same two verbs every run.
The inputs that matter
seed- world seed for the whole generation.prompt_index- the position coordinate. This is the dial you turn to get a different action while keeping the same overall world seed.profile- dropdown ofsubject_action_*.jsonfiles. Drop a custom profile intoprofiles/and restart to see it.prefix/suffix- text wrapped around the output. Useful for forcing a subject reference ("the knight β¦") so the generated verb attaches to the right noun.action_intensity- a filter dropdown (any / subtle / moderate / dynamic / extreme). Honest warning: in v1.0.0 as shipped, this input is accepted but ignored by the generation code. It's declared in the UI, it just doesn't filter yet. Treat it as a placeholder and check for a newer release.
Output is a single text string - wire it to the FLUX2-JSON action field or any text display.
Install
One repo, seventeen nodes - install once and you have them all.
cd ComfyUI/custom_nodes
git clone https://github.com/MushroomFleet/ComfyUI-Zero2JSON
cd ComfyUI-Zero2JSON
pip install -r requirements.txt
Restart ComfyUI. The requirements file is literally one line, xxhash>=3.0.0; nothing heavy, no models, no keys. Or use ComfyUI Manager and search "ComfyUI-Zero2JSON".
Where people get burned
Pairing action with pose wrong is the classic miss: if both nodes fire, you can end up with "standing still" from the pose node and "mid-sprint" from the action node, and the model gets a mixed message. Pick a lane per shot - use action for movement shots and pose for stillness - rather than wiring both into the same subject. And remember the determinism contract: same seed + same prompt_index + same profile equals the same action, every time. That's the feature; it's how you actually hunt for a keeper instead of rerolling blind.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| seed | INT | 00β4294967295 | World seed for deterministic generation |
| prompt_index | INT | 00β4294967295 | Position in infinite prompt space |
| profileopt | COMBO | subject_action_default.json | Select vocabulary profile |
| prefixopt | STRING | Text to prepend to generated prompt | |
| suffixopt | STRING | Text to append to generated prompt | |
| action_intensityopt | COMBO | any | Control action intensity level |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| text | STRING | β |