Nodes/VFX Naming Convention/VFX Naming Convention (Filename Prefix)
ComfyUI Node

VFX Naming Convention (Filename Prefix)

Your Output Is Still Called ComfyUI_00001_.png — Here's the Node That Fixes That

By vctrprzvfx·Created about a month ago·Updated about a month ago· 11
VFX Naming Convention (Filename Prefix)
    • filename_prefix
    • folder_name
    • basename
    • shot_id
    • extension
    • example_filename
    • first_frame
    • report
    ◄show_codeSHW►
    ◄sequence_codeSEQ►
    ◄shot_number10►
    ◄taskcomp►
    ◄vendor_id►
    ◄version1►
    ◄sequence_subfoldertrue►
    ◄stricttrue►
    ◄task_custom►
    ◄plate_layer0►
    ◄parent_path►
    ◄first_frame1001►
    ◄shot_padding4►
    ◄version_padding3►
    ◄frame_padding4►
    ◄file_extensionexr►
    ◄schemavfx_default►
    ◄template_override►
    ◄custom_tokens►

    ComfyUI's filename_prefix is already a small template language - %date:yyyy-MM-dd%, slashes for subfolders. What it can't give you is one agreed string a whole studio can read: SHW_SEQ_0010_comp_vnd_v001.1001.exr, where every field means something to somebody downstream.

    It's a real convention, written up as a paper by Victor Perez, VFX supervisor, and this pack builds it. If you're one person making pictures, you don't need it. If your render has to land in a shot folder next to a comp - or match what a lab plate is already called - you do.

    What it actually is

    One node, category VFX/naming, eight outputs, no models, no dependencies beyond the Python standard library. It saves nothing and touches no pixels - it builds a string, a filename_prefix, that you wire into Save Image, Save Image (Advanced) or a video saver like VHS's Video Combine. (That's the Victor Perez who wrote the naming paper, not Krea's CEO of the same name. Schema-driven design suggested by Sam Hodge; MIT licensed.)

    How it works: the convention is a JSON file

    Almost nothing is hardcoded. Which tokens exist, how each is cased, padded and validated, the delimiters, the token order and the folder depth all live in JSON under schemas/.

    Four ship with it:

    | Schema | Renders | |---|---| | vfx_default | SHW_SEQ_0010_comp_vnd_v001/SHW_SEQ_0010_comp_vnd_v001 | | vfx_flat | same name, no sequence folder | | studio_nested | SHW/SEQ/0010/comp-vnd/v001-0010-comp-vnd | | episodic_dotted | SHW/ep101/SEQ.0010/SHW.SEQ.0010.comp.vp.v001 |

    Templates use {token}, [optional groups] that vanish whole - component and delimiter together - and / for folder depth. Schemas also carry rules, and the shipped one is the interesting bit: if task matches a plate type (mp, bg, fg, el, cp, rp), the vendor id is dropped, because lab plates don't carry one. Drop your own JSON in schemas/ and it appears in the dropdown after a restart.

    The inputs you'll actually set

    show_code and sequence_code are the obvious three-letter fields, auto-uppercased and length-checked. shot_number has a quirk: the +/- arrows step in tens, but you can type anything - 15, 125, 7 - and off-grid numbers are accepted even in strict mode, adding only a note to the report. task is a 32-entry dropdown - four-letter codes, plate types, FINAL for approved shots - and (custom) lets task_custom supply your own. plate_layer turns bg into bg02.

    Then vendor_id (leave it empty for plates - the component and its separator disappear), version, and two switches:

    • sequence_subfolder on renders the schema's folder levels; off writes straight into the output folder.
    • strict on aborts on any violation. Off auto-corrects - shw1 becomes SHW, an over-long task gets trimmed - and lists every issue in the report.

    Once you're tuning, the optional block has first_frame (1001 by default - the convention's plate head), parent_path for an extra sub-path (it takes %date:yyyy-MM-dd%), the three padding fields, file_extension, template_override for a one-off template, and custom_tokens for extras like episode=101.

    Outputs

    filename_prefix is the one you wire - that's the whole point. Right-click the saver's filename_prefix widget → Convert widget to input, then connect (recent frontends also let you drag the output onto the widget). Beyond that: folder_name, basename, shot_id (SHW_SEQ_0010), extension, example_filename, first_frame as an INT for frame-range inputs, and report - a plain-text breakdown plus warnings. Watch report while you set up.

    Install

    No dependencies, so this is the easy kind of install. In ComfyUI Manager use Install via Git URL and paste the repo URL, or manually:

    cd ComfyUI/custom_nodes
    git clone https://github.com/vctrprzvfx/ComfyUI-VFX-Naming.git
    

    Restart ComfyUI, then add the node from VFX/naming.

    The thing everybody gets wrong

    Your prefix is not your file. ComfyUI's own savers always append their own counter and extension, so a prefix of SHW_SEQ_0010_comp_vnd_v001 lands on disk as:

    SHW_SEQ_0010_comp_vnd_v001/SHW_SEQ_0010_comp_vnd_v001_00001_.png
    

    The folder and everything up to the version are exactly right. The .1001.exr tail is the saver's, not the prefix's - stock ComfyUI counts _00001_ from 1. Savers with their own format widget (Save Image Advanced variants, VHS Video Combine) honour what you pick there, and extension / example_filename / first_frame exist so you can drive one. A literal basename.1001.exr on disk needs a saver that writes the frame token itself. Actual scene-linear EXR is the OCIO/OpenImageIO packs' job (comfy_oiio, the Nuke-style sets), not this one's.

    Two more: strict on means a bad value stops the workflow right here, so read the message instead of assuming breakage - or flip strict off and read report. And if the shot-number arrows go weird after an update, hard-refresh the browser (Cmd/Ctrl+Shift+R); the stepping is bundled JavaScript your browser caches, and it's a custom widget, so odd buttons on the Nodes 2.0 frontend are the frontend's fault.

    CategoryVFX/naming

    Inputs (19)

    NameTypeDefaultDescription
    show_codeSTRINGSHWShow code: 3 letters, uppercase (e.g. SHW).
    sequence_codeSTRINGSEQSequence/block code: 3 letters, uppercase (e.g. SEQ).
    shot_numberINT100–999999Shot number, zero padded. The arrows step in tens (the convention's increment), but any number can be typed in manually - 15, 0125, whatever the show uses.
    taskCOMBOcompTask code: 4 lowercase letters, a 2-character lab plate type (mp/bg/fg/el/cp/rp), FINAL for approved shots, or (custom).
    vendor_idSTRINGVendor id: 3 letters, lowercase. Leave empty for lab plates - the component and its delimiter are dropped.
    versionINT10–999999Version number, 'v' prefixed and zero padded.
    sequence_subfolderBOOLEANtrueRender the schema's folder levels. Off writes the files straight into the output folder.
    strictBOOLEANtrueStrict: abort on any violation. Permissive: auto-correct and list the issues in the report output.
    task_customoptSTRINGTask code used when 'task' is set to (custom).
    plate_layeroptINT00–99Layer number appended to plate tasks (0 = none): bg -> bg02.
    parent_pathoptSTRINGOptional sub-path under the output folder, e.g. 'SHW/SEQ' or '%date:yyyy-MM-dd%'.
    first_frameoptINT10010–9999999First frame of the work range (plate head). Convention: 1001.
    shot_paddingoptINT41–8—
    version_paddingoptINT31–8—
    frame_paddingoptINT41–10—
    file_extensionoptCOMBOexrFile extension for the 'extension' and 'example_filename' outputs. ComfyUI savers pick their own format widget-side; this drives downstream nodes and the preview.
    schemaoptCOMBOvfx_defaultNaming schema from the schemas/ folder: token rules, delimiters, token order and folder depth. Drop your own JSON in there to add a studio convention.
    template_overrideoptSTRINGOverride the schema's templates for one node. Use {token}, [optional groups] and / for folder levels, e.g. {show}/{seq}/{show}_{seq}_{shot}_{task}[_{vendor}]_{version}
    custom_tokensoptSTRINGExtra tokens for the template, one 'name=value' per line, e.g. episode=101. Reference them as {episode}.

    Outputs (8)

    NameTypeDescription
    filename_prefixSTRINGConnect to filename_prefix on Save Image / Save Image (Advanced) / video savers.
    folder_nameSTRINGFolder levels the schema renders (empty when there are none).
    basenameSTRINGFilename without frame number or extension.
    shot_idSTRINGShow_Sequence_Shot identifier.
    extensionSTRINGFile extension, lowercase and without a leading dot.
    example_filenameSTRINGFully formed example filename including frame and extension.
    first_frameINTFirst frame of the work range.
    reportSTRINGHuman-readable breakdown plus any validation warnings.