Symbiotica Asset Recipe
The asset and every knob that draws it, on one node
- order
- asset_name
- category
- client_prompt
- save_path
- order
- event_order
- bucket
- ref_image
- ref_mask
- ref_name
- category_recipe
- width
- height
- slot_1
- slot_2
- slot_3
- slot_4
- slot_5
- slot_6
- slot_7
- slot_8
- slot_9
- slot_10
- slot_11
- slot_12
- slot_13
- slot_14
- slot_15
- slot_16
What this node is for
This node only makes sense inside a particular way of working. You render game assets one at a time off an order sheet - a client's monthly .xlsx listing every item they want art for. Each asset needs its own prompt, its own reference image, and a handful of settings true for that asset and no other: which LoRA, that LoRA's strength, the seed, the denoise.
In a normal graph those values live in widgets scattered across the canvas, so moving to the next asset means re-dialing five things and hoping you found all of them. Symbiotica Asset Recipe moves them onto the node that picked the asset: one node per asset, the whole recipe in one place.
How it works
Structurally it's the pack's Symbiotica Asset Focus with slots bolted on - same inputs, and every Asset Focus output appears here in the same order. On the end it adds sixteen slot_1 … slot_16 outputs (wildcard type) and a hidden slots string widget, the table the canvas writes and Python reads.
The gesture: drag a wire from the empty + widget output at the foot of the output column onto a widget's socket on another node - a LoRA strength, a seed, a denoise. The node reads the name, type and current value off the far end, records them as a slot, turns that far widget link-driven and opens a fresh empty slot below. A small widget appears on the node so you can type the value there.
The slot block rides in that one slots JSON string and the per-slot widgets are marked non-serialising, because ComfyUI restores a saved graph's widget values by position - a growing block of real widgets would shift every value below it. Each row converts back to its original type (a seed stays an INT, not a float the sampler refuses), and unreadable JSON counts as no slots rather than a crash.
Inputs you actually set
category- narrow the picker to one asset type, or empty for all of them.asset- which asset, set by clicking it on the node. Empty means the first - unless you want every asset in the event, in which case leaving it empty emits one item per asset and the graph downstream runs once each. Typed names work too; a name that no longer exists raises an error listing what the event actually holds.project_path/month/feature- read only when nothing is wired intoorder, and this node then does the whole selection itself.featurepicks which event of that month.ref- which of the client's reference images to emit, by filename; clicking a thumbnail on the node sets it. Empty means the first, which is what every other asset gets in an all-assets run.
What comes out
asset_name, category and client_prompt are what you'd expect, and save_path is month/feature/category/asset - it drops straight into a Save Image's filename_prefix, no string-joining. Then the asset's record: order, narrowed to this asset, and event_order, the whole event unnarrowed, for the Order Tracker; bucket, the sub-kind of a category (Drinks); ref_image / ref_mask / ref_name, the client reference you clicked and its alpha; category_recipe, the category plus its canvas in tiles (Appliance 1x2 - a 128x128 and a 128x256 Appliance are genuinely two recipes); and width / height, that canvas in pixels, for saving at the game's own size. Then slot_1 … slot_16.
One split worth knowing: the asset-level outputs are lists and fan out over a whole event, while the slots are single values shared by every asset in that run.
Installing it
ComfyUI Manager → search Symbiotica → install, then restart. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/symbiotica-ai/comfyui-nodes.git symbiotica
pip install -r symbiotica/requirements.txt
Dependencies are requests and pillow - nothing heavy, usually already there. No API key is involved here; the keys in the README belong to the pack's Claude and Gemini nodes.
The setup that actually bites: project_path is a project folder - one with an orders/ subfolder (the monthly .xlsx, the per-month client-refs folders) and a reference-assets/ folder. A project living outside ComfyUI's own input/ and output/ also has to be declared, in Settings → Symbiotica → Paths → Asset folders or:
export SYMBIOTICA_ASSET_ROOTS="/Users/me/games/my-game, /Volumes/art"
Without that the project browser comes up empty, which reads as a broken node but is a permissions story: naming a folder in a request can't make it readable.
Where people get burned
Dragging a MODEL or IMAGE socket onto a slot gets refused with a toast, and rightly so - a slot holds a value you can type, not a model. That's the most common first attempt.
Empty asset means everything, not nothing: leave the field blank when you wanted one asset and you queue the whole event. A slot also only adopts a drag when it's the empty one at the foot - an existing slot taking a second wire drives both widgets from the one value - and removing a slot is the right-click menu on its dot.
Finally, don't confuse this with the pack's Recipes node, which is a different feature entirely: a project, a template workflow, and one generated workflow per recipe. Asset Focus and Asset Recipe are the selection layer; Recipes is about generating workflows. Same word, different thing.
One last thing: this pack is written against ComfyUI's newer V3 node API, and it's a studio tool rather than a community darling, so there's no pile of forum threads to fall back on. On an old ComfyUI the console prints [Symbiotica] Failed to load … with a traceback and the whole pack vanishes at once. Update ComfyUI.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| category | STRING | Narrow the choice to one asset type. Empty is the whole event, and the first asset of it is what runs. | |
| asset | STRING | Which asset, by name. Set by clicking it on the node; typed names work too. Empty means the first. | |
| orderopt | SYMBIOTICA_ORDER | — | |
| project_pathopt | STRING | The project folder, the one with an orders/ subfolder. Only read when no order is wired in — this node then does the whole selection itself. | |
| monthopt | STRING | — | |
| featureopt | STRING | Which event of that month. Empty means the order's first. | |
| refopt | STRING | Which of the asset's client references to emit, by filename. Set by clicking a thumbnail on the node. Empty means the first. | |
| slotsopt | STRING | [] | The slot table, as JSON. Set by wiring widgets to this node. |
Outputs (29)
| Name | Type | Description |
|---|---|---|
| asset_name | STRING | — |
| category | STRING | — |
| client_prompt | STRING | — |
| save_path | STRING | month/feature/category/asset — where this asset's renders are filed. A Save Image's filename_prefix takes it as is, and so does the Order Tracker. |
| order | SYMBIOTICA_ORDER | The incoming order narrowed to each focused asset — same event, same project, a one-asset assets list. One of these per focused asset, so downstream still runs once per asset. |
| event_order | SYMBIOTICA_ORDER | The WHOLE event, unnarrowed. The Order Tracker wants the event rather than the asset, and it must not change every time you focus a different one. |
| bucket | STRING | Which sub-kind of its category this asset is — `Drinks` for a Food row whose Prep line is an empty cup, empty for everything else. It names `<category> - <bucket>` where the prompt book holds one. |
| ref_image | IMAGE | The client reference you clicked, one per focused asset, composited onto the sheet grey. An asset the client sent no art for gets a one-pixel plate and an empty `ref_name`. |
| ref_mask | MASK | That reference's alpha, opaque where the art is. |
| ref_name | STRING | Its filename — which reference was drawn. Empty when the asset has no references at all. |
| category_recipe | STRING | The category plus its canvas in tiles: `Appliance 1x2`. What a recipe is named after. |
| width | INT | The asset's canvas width in pixels, 0 when the sheet names none. |
| height | INT | The asset's canvas height in pixels, 0 when the sheet names none. |
| slot_1 | * | — |
| slot_2 | * | — |
| slot_3 | * | — |
| slot_4 | * | — |
| slot_5 | * | — |
| slot_6 | * | — |
| slot_7 | * | — |
| slot_8 | * | — |
| slot_9 | * | — |
| slot_10 | * | — |
| slot_11 | * | — |
| slot_12 | * | — |
| slot_13 | * | — |
| slot_14 | * | — |
| slot_15 | * | — |
| slot_16 | * | — |