Nodes/comfyui-nodes/Symbiotica Asset Recipe
ComfyUI Node

Symbiotica Asset Recipe

The asset and every knob that draws it, on one node

By symbiotica-ai·Created 6 months ago·Updated about 12 hours ago· 3
Symbiotica Asset Recipe
  • 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
◄category►
◄asset►
◄project_path►
◄month►
◄feature►
◄ref►
◄slots[]►

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 into order, and this node then does the whole selection itself. feature picks 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.

CategorySymbiotica

Inputs (8)

NameTypeDefaultDescription
categorySTRINGNarrow the choice to one asset type. Empty is the whole event, and the first asset of it is what runs.
assetSTRINGWhich asset, by name. Set by clicking it on the node; typed names work too. Empty means the first.
orderoptSYMBIOTICA_ORDER—
project_pathoptSTRINGThe project folder, the one with an orders/ subfolder. Only read when no order is wired in — this node then does the whole selection itself.
monthoptSTRING—
featureoptSTRINGWhich event of that month. Empty means the order's first.
refoptSTRINGWhich of the asset's client references to emit, by filename. Set by clicking a thumbnail on the node. Empty means the first.
slotsoptSTRING[]The slot table, as JSON. Set by wiring widgets to this node.

Outputs (29)

NameTypeDescription
asset_nameSTRING—
categorySTRING—
client_promptSTRING—
save_pathSTRINGmonth/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.
orderSYMBIOTICA_ORDERThe 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_orderSYMBIOTICA_ORDERThe 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.
bucketSTRINGWhich 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_imageIMAGEThe 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_maskMASKThat reference's alpha, opaque where the art is.
ref_nameSTRINGIts filename — which reference was drawn. Empty when the asset has no references at all.
category_recipeSTRINGThe category plus its canvas in tiles: `Appliance 1x2`. What a recipe is named after.
widthINTThe asset's canvas width in pixels, 0 when the sheet names none.
heightINTThe 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*—