BD Save File
The save node that speaks every type the pack uses
- data
- alpha_mask
- data
- file_path
- status
ComfyUI's built-in SaveImage only speaks IMAGE. BD Save File speaks everything the BrainDead pack actually produces - IMAGE, MASK, AUDIO, LATENT, STRING, TRIMESH - and it's the node that ties the pack's file discipline together. Whether you're caching a mesh, dumping a PBR map, or parking a prompt string next to your renders, one node does it, and it slots into the BD Save Context system so filenames stop being a mess.
What it is
A universal save node: wire in data of almost any type, it picks the right native format and writes it to disk, then hands you back the file_path as a STRING (and passes the data through unchanged). It's the same "save" node the README builds the whole caching/iteration story on.
How it works
The type determines the format - IMAGE → PNG, MASK → PNG, LATENT → safetensors, AUDIO → WAV, STRING → TXT, TRIMESH → PLY. You don't pick the format; it detects it. Where it gets interesting is context integration:
- With a BD Save Context registered and
context_idmatched, the path resolves from the context's template plus this node'ssuffix/filename/name_prefix/custom_vars. One context, N save nodes, all consistent. - Without a context (or with zero/multiple contexts registered and an empty
context_id), it falls back to legacy behavior:filename+ optionalname_prefixinto the output folder.
The inputs that matter
data- the any-type input. This is the whole reason to use it.filename- with a context it overrides%name%/%filename%in the template; without one it's the literal filename.context_id+suffix-_albedo,_shoes,_head. The README suggests wiringsuffixfromBD For Each Run.labelor an iterator's tag for per-iteration filenames.skip_if_exists(default true) - don't clobber existing files; report the existing path instead.extension- override the auto-detected one, for the rare case you want a different container.alpha_mask/invert_alpha/save_alpha_separately- bake a mask into the saved file's alpha channel (white = opaque), and optionally write a sidecar_alpha.png. Conventions matter here: white = opaque, black = transparent, and ComfyUI's LoadImage mask output is the inverse of the subject - flipinvert_alphaif your mask has white=background.
Outputs: data (passthrough, so you can chain), file_path (absolute path as a STRING - wire it into anything that wants a path), and status.
Where it shines
The README's example says it best: [BD Prompt Iterator] → [BD Qwen Character Edit] → [BD Save File] with name_prefix: MyCharacter - iterate through a character sheet and land clean, sequentially-named files. And in the PBR pipeline, five maps out of BD Derive PBR Maps all funnel into one context-aware save. If you've ever hunted through output/ for the file that SaveImage_0001 actually wrote, you'll appreciate getting a real path back.
Installing it
ComfyUI Manager: search "BrainDead" → install. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/BizaNator/ComfyUI-BrainDead
cd ComfyUI-BrainDead
pip install -r requirements.txt
Restart, find it under 🧠BrainDead/Cache. No extra dependencies beyond what ComfyUI already has - trimesh (for TRIMESH saves) ships with modern ComfyUI, and the audio/latent paths use native ComfyUI formats.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| data | * | — | |
| filename | STRING | saved_file | With context: overrides %name% / %filename% in template if set (non-'saved_file'). Without context: legacy filename. |
| skip_if_exists | BOOLEAN | true | — |
| name_prefixopt | STRING | With context: exposed as %name_prefix% in template. Without context: legacy prefix prepended to filename. | |
| extensionopt | STRING | Override auto-detected extension. | |
| context_idopt | STRING | If set AND a BD_SaveContext with this id is registered: path is resolved from the context's template + this node's suffix/filename/name_prefix. If empty AND exactly ONE context is registered, that one is auto-used. If empty AND zero or multiple contexts: legacy filename-based behavior. | |
| suffixopt | STRING | Per-save suffix appended after filename (e.g. '_albedo', '_shoes', '_head'). Wire from BD_ForEachRun.label or Iterator.tag for per-iteration filenames. With context: also exposed as %suffix% in the template. Without context: appended literally to filename — caller controls separator (convention: leading underscore). | |
| custom_varsopt | STRING | Per-save extra variables, one per line as key=value. Layered ON TOP of the context's custom_vars (this node's keys override context for matching names). Examples: subfolder=textures materials=metal pass=normal These become %subfolder%, %materials%, %pass% in the template. Empty values resolve cleanly (// → /). Undefined vars stay as %var% literals so you spot typos. | |
| save_alpha_separatelyopt | BOOLEAN | false | Also write the alpha channel as a standalone greyscale PNG alongside the main file, named with the same suffix + '_alpha'. Source of the alpha pixels: • alpha_mask wired → uses the mask (after invert_alpha) • no mask wired, image has 4 channels (RGBA) → extracts the embedded A channel • no mask wired, image is RGB (3ch) → no alpha to extract; this output is skipped NOTE: the _alpha.png is a RAW greyscale representation — white pixel = opaque area, black pixel = transparent area. It is NOT a composited preview; open the main RGBA PNG in a viewer that supports transparency to see the actual cut-out. |
| alpha_maskopt | MASK | Bake this mask into the saved file's alpha channel before writing. Convention: WHITE (1.0) = OPAQUE, BLACK (0.0) = TRANSPARENT. Face mask (white face, black background) → face is opaque, background is cut out. Background mask (white background, black face) → use invert_alpha=True. If you already have an RGBA image (4-channel), you do NOT need to wire alpha_mask — the embedded alpha is preserved automatically when saving. The upstream image tensor is NOT modified — transparency is baked only in the saved file. Accepts batched masks (B, H, W); single (H,W) or (1,H,W) applies to all frames. | |
| invert_alphaopt | BOOLEAN | false | Flip the mask polarity before baking as alpha. Use when your mask has white=background / black=subject and you want the subject opaque. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| data | * | — |
| file_path | STRING | — |
| status | STRING | — |